using Model; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; namespace BLL { public class TwArrivalStatisticsService { public static List GetStatistics(string projectid, string materialCode, string WarehouseCode) { using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString)) { string WarehouseId = Base_WarehouseService.GetWarehouseList(projectid).Where(x => x.WarehouseName == WarehouseCode).Select(x => x.WarehouseId).FirstOrDefault(); ///所需材料数量列表 var NeedOutMateriaList = from x in db.HJGL_PipeLineMat join y in db.HJGL_MaterialCodeLib on x.MaterialCode equals y.MaterialCode join z in db.HJGL_Pipeline on x.PipelineId equals z.PipelineId where z.ProjectId == projectid && (string.IsNullOrEmpty(materialCode) || x.MaterialCode.Contains(materialCode)) && z.WarehouseId == WarehouseId group x by x.MaterialCode into g select new { g.Key, NeedNum = g.Sum(x => x.Number) ?? 0, }; ///实际材料入库数量列表 var RealInMateriaList = (from x in db.Tw_InputDetail join master in db.Tw_InputMaster on x.InputMasterId equals master.Id join y in db.HJGL_MaterialCodeLib on x.MaterialCode equals y.MaterialCode where master.ProjectId == projectid && master.WarehouseCode == WarehouseCode group x by x.MaterialCode into g where (string.IsNullOrEmpty(materialCode) || g.Key.Contains(materialCode)) select new { g.Key, RealNum = g.Sum(x => x.ActNum) ?? 0, }).ToList(); //库存数量 var tw_MaterialStock = (from x in db.Tw_MaterialStock where x.WarehouseCode == WarehouseCode && x.ProjectId == projectid select x).ToList(); var needMateriaList = NeedOutMateriaList.ToList(); var materialCodeList = needMateriaList.Select(x => x.Key) .Union(RealInMateriaList.Select(x => x.Key)) .Distinct() .ToList(); var materialInfoList = (from x in db.HJGL_MaterialCodeLib where materialCodeList.Contains(x.MaterialCode) select x).ToList(); var StatisticsList = (from code in materialCodeList join x in needMateriaList on code equals x.Key into needGroup from x in needGroup.DefaultIfEmpty() join y in RealInMateriaList on code equals y.Key into realGroup from y in realGroup.DefaultIfEmpty() join z in materialInfoList on code equals z.MaterialCode into infoGroup from z in infoGroup.DefaultIfEmpty() join m in tw_MaterialStock on code equals m.PipeLineMatCode into stockGroup from m in stockGroup.DefaultIfEmpty() orderby code select new Tw_ArrivalStatisticsOutPut { MaterialCode = code, StockNum = m == null ? 0 : (decimal)m.StockNum, NeedNum = x == null ? 0 : x.NeedNum, RealNum = y == null ? 0 : y.RealNum, MaterialName = z == null ? null : z.MaterialName, MaterialSpec = z == null ? null : z.MaterialSpec, MaterialUnit = z == null ? null : z.MaterialUnit, MaterialDef = z == null ? null : z.MaterialDef, MatchRate = (x == null || x.NeedNum == 0 ? 0 : Math.Round((y == null ? 0 : y.RealNum) / x.NeedNum, 4, MidpointRounding.ToEven)), }).ToList(); foreach (var item in StatisticsList) { item.MatchRateString = Math.Round(item.MatchRate * 100, 2).ToString() + "%"; } return StatisticsList; } } /// /// 根据所需材料列表和库存列表获取匹配结果 /// /// /// /// /// public static List GetMatMatchOutput(List requiredMaterials, string warehouseCode, string projectId) { Tw_MaterialStockOutput twMaterialStockOutput = new Tw_MaterialStockOutput { WarehouseCode = warehouseCode, ProjectId = projectId }; var stockList = TwMaterialstockService.GetTw_MaterialStockByModle(twMaterialStockOutput).ToList();//获取库存列表 // 预扣除出库申请单中状态为待审核/已审核的材料数量 using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString)) { var outboundMaterials = from detail in db.Tw_InOutPlanDetail join master in db.Tw_InOutPlanMaster on detail.InOutPlanMasterId equals master.Id where master.InOutType == (int)TwConst.InOutType.出库 && (master.State == (int)TwConst.State.待审核 || master.State == (int)TwConst.State.已审核) && master.WarehouseCode == warehouseCode && master.ProjectId == projectId group detail by detail.MaterialCode into g select new { MaterialCode = g.Key, TotalPlanNum = g.Sum(d => d.PlanNum) ?? 0 }; var outboundList = outboundMaterials.ToList(); foreach (var outbound in outboundList) { var stock = stockList.FirstOrDefault(x => x.PipeLineMatCode == outbound.MaterialCode); if (stock != null) { stock.StockNum -= outbound.TotalPlanNum; } } } foreach (var material in requiredMaterials) { material.Id = Guid.NewGuid().ToString(); var thisMaterialStockNum = stockList.FirstOrDefault(x => x.PipeLineMatCode == material.MaterialCode)?.StockNum ?? 0; if (thisMaterialStockNum >= material.NeedNum) { material.MatchNum = material.NeedNum; material.MatchRate = 1; material.MatchRateString = "100%"; } else { material.MatchNum = thisMaterialStockNum < 0 ? 0 : thisMaterialStockNum; material.MatchRate = (material.NeedNum == 0 ? 0 : ((material.MatchNum ?? 0) / material.NeedNum)); material.MatchRateString = Math.Round((decimal)(material.MatchRate ?? 0) * 100, 2).ToString() + "%"; } //修改stockList对应的库存数量 var stock = stockList.FirstOrDefault(x => x.PipeLineMatCode == material.MaterialCode); if (stock != null) { stock.StockNum -= material.MatchNum; } } var results = requiredMaterials; return results; } /// /// 获取管线匹配率 /// /// /// public static decimal? GetPipeMatch(string pipelineId) { using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString)) { var twPipeMatMatchOutputs = new List(); List pipelineIds = new List(); pipelineIds.Add(pipelineId); var pipelineModel = PipelineService.GetPipelineByPipelineId(pipelineId); string warehouseCode = BLL.Base_WarehouseService.GetWarehouseByWarehouseId(PipelineService.GetPipelineByPipelineId(pipelineModel.PipelineId).WarehouseId).WarehouseName; var PipeMatMatch = GetPipeMatMatch(pipelineModel.ProjectId, pipelineIds, warehouseCode); var pipeMatchRate = GetPipeMatch(PipeMatMatch).FirstOrDefault(x => x.PipelineId == pipelineId); return pipeMatchRate?.MatchRate; } } /// /// 根据出库单主键获取材料匹配信息 /// /// /// public static List GetMatMatchByOutPlanMasterId(string outPlanMasterId) { using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString)) { var results = new List(); string[] taskPipeLineList = null; var inoutPlanMasterl = db.Tw_InOutPlanMaster.FirstOrDefault(x => x.Id == outPlanMasterId); if (inoutPlanMasterl != null) { if (inoutPlanMasterl.WeldTaskId.Split('|').Length == 4) { taskPipeLineList = Funs.DB.View_HJGL_WeldingTask.Where(e => e.UnitWorkId == inoutPlanMasterl.WeldTaskId.Split('|')[0].ToString() && e.UnitId == inoutPlanMasterl.WeldTaskId.Split('|')[1].ToString() && e.TaskDate.Value.Date == DateTime .ParseExact(inoutPlanMasterl.WeldTaskId.Split('|')[2].ToString(), "yyyyMMdd", null).Date && e.SerialNumber == inoutPlanMasterl.WeldTaskId.Split('|')[3].ToString() ).Distinct().OrderBy(x => x.PipeLineSortIndex).Select(x => x.PipelineId).ToArray(); } } // 获取所需材料列表 var requiredMaterials = (from x in db.Tw_InOutPlanDetail_Relation join master in db.Tw_InOutPlanMaster on x.InOutPlanMasterId equals master.Id join y in db.HJGL_MaterialCodeLib on x.MaterialCode equals y.MaterialCode join z in db.HJGL_Pipeline on x.PipelineId equals z.PipelineId where x.InOutPlanMasterId == outPlanMasterId select new Tw_PipeMatMatchOutput { Id = Guid.NewGuid().ToString(), PipelineId = x.PipelineId, PipelineCode = z.PipelineCode, PrefabricatedComponents = x.PrefabricatedComponents, MaterialCode = x.MaterialCode, MaterialName = y.MaterialName, MaterialSpec = y.MaterialSpec, MaterialUnit = y.MaterialUnit, MaterialDef = y.MaterialDef, NeedNum = x.Number } ).ToList(); if (taskPipeLineList != null && taskPipeLineList.Any()) { requiredMaterials = requiredMaterials.OrderBy(x => Array.IndexOf(taskPipeLineList, x.PipelineId.ToString())).ToList(); } var masterModle = db.Tw_InOutPlanMaster.FirstOrDefault(x => x.Id == outPlanMasterId); results = GetMatMatchOutput(requiredMaterials, masterModle.WarehouseCode, masterModle.ProjectId); return results; } } /// /// 根据管线id获取材料匹配信息 /// /// /// /// /// public static List GetPipeMatMatch(string projectId, List pipelineIds, string warehouseCode) { using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString)) { var results = new List(); // 获取所需材料列表 var requiredMaterials = (from x in db.HJGL_PipeLineMat join y in db.HJGL_MaterialCodeLib on x.MaterialCode equals y.MaterialCode join z in db.HJGL_Pipeline on x.PipelineId equals z.PipelineId join m in db.WBS_UnitWork on z.UnitWorkId equals m.UnitWorkId where z.ProjectId == projectId && pipelineIds.Contains(z.PipelineId) && x.PrefabricatedComponents != "" //x.PrefabricatedComponents!="" 用于筛选非散件材料 select new Tw_PipeMatMatchOutput { Id = Guid.NewGuid().ToString(), PipelineId = x.PipelineId, PipelineCode = z.PipelineCode, UnitWorkId = z.UnitWorkId, UnitWorkName = m.UnitWorkName, PrefabricatedComponents = x.PrefabricatedComponents, MaterialCode = x.MaterialCode, MaterialName = y.MaterialName, MaterialSpec = y.MaterialSpec, MaterialUnit = y.MaterialUnit, MaterialDef = y.MaterialDef, NeedNum = x.Number, } ).ToList(); var newRequiredMaterials = new List(); foreach (string id in pipelineIds) { newRequiredMaterials.AddRange(requiredMaterials.Where(x => x.PipelineId == id)); } results = GetMatMatchOutput(newRequiredMaterials, warehouseCode, projectId); return results; } } /// /// 根据管线材料匹配结果,获取管线匹配率 /// /// /// public static List GetPipeMatch(List twPipeMatMatch) { var result = twPipeMatMatch .GroupBy(item => new { item.PipelineId, item.PipelineCode, item.UnitWorkName }) // 按 PipelineId 和 PipelineCode 分组 .Select(group => new Tw_PipeMatchOutput { PipelineId = group.Key.PipelineId, // 当前组的 PipelineId PipelineCode = group.Key.PipelineCode, // 当前组的 PipelineCode UnitWorkName = group.Key.UnitWorkName, // 当前组的 UnitWorkName SumNeedNum = group.Sum(item => item.NeedNum), SumMatchNum = group.Sum(item => item.MatchNum), MatchRate = group.Sum(item => item.MatchNum) > 0 && group.Sum(item => item.NeedNum) > 0 ? (decimal)group.Sum(item => item.MatchNum) / (decimal)group.Sum(item => item.NeedNum) : 0, MatchRateString = Math.Round((decimal)group.Sum(item => item.MatchNum) / (decimal)group.Sum(item => item.NeedNum) * 100, 2).ToString() + "%" }) .ToList(); // 转换为 List return result; } } }