575 lines
32 KiB
C#
575 lines
32 KiB
C#
|
|
using Model;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace BLL
|
|
{
|
|
public class TwArrivalStatisticsService
|
|
{
|
|
public static List<Tw_ArrivalStatisticsOutPut> 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.WarehouseId == WarehouseCode || 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.WarehouseId == WarehouseId
|
|
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.WarehouseId == WarehouseId && 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,
|
|
Code = z == null ? null : z.Code,
|
|
HeatNo = z == null ? null : z.HeatNo,
|
|
BatchNo = z == null ? null : z.BatchNo,
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据所需材料列表和库存列表获取匹配结果
|
|
/// </summary>
|
|
/// <param name="requiredMaterials"></param>
|
|
/// <param name="warehouseCode"></param>
|
|
/// <param name="projectId"></param>
|
|
/// <returns></returns>
|
|
public static List<Tw_PipeMatMatchOutput> GetMatMatchOutput(List<Tw_PipeMatMatchOutput> requiredMaterials, string warehouseCode, string projectId, bool matchByMaterialCodeLibCode = false)
|
|
{
|
|
Tw_MaterialStockOutput twMaterialStockOutput = new Tw_MaterialStockOutput
|
|
{
|
|
WarehouseId = 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.WarehouseId == 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();
|
|
// 材料导入只保存材料编码 Code,匹配时按 Code 从库存中挑选实际材料主编码 PipeLineMatCode。
|
|
var stock = matchByMaterialCodeLibCode
|
|
? stockList
|
|
.Where(x => x.Code == material.MaterialCode && (x.StockNum ?? 0) > 0)
|
|
// 优先选择库存能覆盖本条需求的材料主编码,再按主编码稳定排序,保证匹配结果可复现。
|
|
.OrderByDescending(x => (x.StockNum ?? 0) >= (material.NeedNum ?? 0))
|
|
.ThenBy(x => x.PipeLineMatCode)
|
|
.FirstOrDefault()
|
|
: stockList.FirstOrDefault(x => x.PipeLineMatCode == material.MaterialCode);
|
|
var thisMaterialStockNum = stock?.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() + "%";
|
|
|
|
}
|
|
// 这里保存的是本次计算匹配到的临时材料主编码;是否已反写以 HJGL_PipeLineMat.MaterialCode 为准。
|
|
material.MatchMaterialCode = stock?.PipeLineMatCode;
|
|
// 本轮匹配会连续消耗同一库存快照,防止后续材料重复占用已匹配数量。
|
|
if (stock != null)
|
|
{
|
|
stock.StockNum -= material.MatchNum;
|
|
}
|
|
}
|
|
|
|
var results = requiredMaterials;
|
|
return results;
|
|
}
|
|
/// <summary>
|
|
/// 获取管线匹配率
|
|
/// </summary>
|
|
/// <param name="pipelineId"></param>
|
|
/// <returns></returns>
|
|
public static decimal? GetPipeMatch(string pipelineId)
|
|
{
|
|
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
|
|
{
|
|
var twPipeMatMatchOutputs = new List<Tw_PipeMatMatchOutput>();
|
|
List<string> pipelineIds = new List<string>();
|
|
pipelineIds.Add(pipelineId);
|
|
var pipelineModel = PipelineService.GetPipelineByPipelineId(pipelineId);
|
|
string warehouseCode = PipelineService.GetPipelineByPipelineId(pipelineModel.PipelineId).WarehouseId;
|
|
var PipeMatMatch = GetPipeMatMatch(pipelineModel.ProjectId, pipelineIds, warehouseCode);
|
|
var pipeMatchRate = GetPipeMatch(PipeMatMatch).FirstOrDefault(x => x.PipelineId == pipelineId);
|
|
return pipeMatchRate?.MatchRate;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 根据出库单主键获取材料匹配信息
|
|
/// </summary>
|
|
/// <param name="outPlanMasterId"></param>
|
|
/// <returns></returns>
|
|
public static List<Tw_PipeMatMatchOutput> GetMatMatchByOutPlanMasterId(string outPlanMasterId)
|
|
{
|
|
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
|
|
{
|
|
var results = new List<Tw_PipeMatMatchOutput>();
|
|
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,
|
|
Code = y.Code,
|
|
HeatNo = y.HeatNo,
|
|
BatchNo = y.BatchNo,
|
|
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.WarehouseId, masterModle.ProjectId);
|
|
return results;
|
|
}
|
|
|
|
|
|
}
|
|
/// <summary>
|
|
/// 根据管线id获取材料匹配信息
|
|
/// </summary>
|
|
/// <param name="projectId"></param>
|
|
/// <param name="pipelineIds"></param>
|
|
/// <param name="warehouseCode"></param>
|
|
/// <returns></returns>
|
|
public static List<Tw_PipeMatMatchOutput> GetPipeMatMatch(string projectId, List<string> pipelineIds, string warehouseCode, Dictionary<string, List<string>> priorityWeldJoints = null, string pipeArea = null)
|
|
{
|
|
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
|
|
{
|
|
var results = new List<Tw_PipeMatMatchOutput>();
|
|
if (pipelineIds == null || !pipelineIds.Any())
|
|
{
|
|
return results;
|
|
}
|
|
pipelineIds = pipelineIds.Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList();
|
|
if (!pipelineIds.Any())
|
|
{
|
|
return results;
|
|
}
|
|
|
|
// 先保留当前区域内已焊和未焊数据,用于识别“已经开工但尚未完成”的续作组件。
|
|
var pipeLineMatQuery = from x in db.HJGL_PipeLineMat
|
|
join z in db.HJGL_Pipeline on x.PipelineId equals z.PipelineId
|
|
join m in db.WBS_UnitWork on z.UnitWorkId equals m.UnitWorkId
|
|
join w in db.HJGL_WeldJoint on x.WeldJointId equals w.WeldJointId into weldJoin
|
|
from w in weldJoin.DefaultIfEmpty()
|
|
// 先保留组件全部材料行,避免数量为0的历史已焊口导致续作组件识别遗漏。
|
|
where z.ProjectId == projectId && pipelineIds.Contains(z.PipelineId)
|
|
&& x.PrefabricatedComponents != null && x.PrefabricatedComponents != ""
|
|
select new
|
|
{
|
|
PipeLineMat = x,
|
|
PipelineCode = z.PipelineCode,
|
|
UnitWorkId = z.UnitWorkId,
|
|
UnitWorkName = m.UnitWorkName,
|
|
WeldJoint = w
|
|
};
|
|
|
|
string jointAttribute = GetJointAttributeByPipeArea(pipeArea);
|
|
bool filterByPipeArea = !string.IsNullOrEmpty(jointAttribute);
|
|
if (filterByPipeArea)
|
|
{
|
|
// 页面用途以材料表 PipeArea 为准,工厂/现场只能匹配相应类型的焊口。
|
|
pipeLineMatQuery = pipeLineMatQuery.Where(x => x.PipeLineMat.PipeArea == pipeArea
|
|
&& x.WeldJoint != null
|
|
&& x.WeldJoint.JointAttribute == jointAttribute);
|
|
}
|
|
|
|
var allPipeLineMats = pipeLineMatQuery.ToList();
|
|
var continuationComponentKeys = new HashSet<string>(allPipeLineMats
|
|
.Where(x => x.WeldJoint != null && !string.IsNullOrEmpty(x.WeldJoint.WeldingDailyId))
|
|
.Select(x => GetComponentKey(x.PipeLineMat.PipelineId, x.PipeLineMat.PrefabricatedComponents)));
|
|
|
|
// 页面匹配只展示并消耗尚未焊接的焊口材料;不传区域的旧调用保留原查询行为。
|
|
var pipeLineMats = filterByPipeArea
|
|
? allPipeLineMats.Where(x => x.WeldJoint != null
|
|
&& x.WeldJoint.WeldingDailyId==null
|
|
&& (x.PipeLineMat.Number ?? 0) > 0).ToList()
|
|
: allPipeLineMats.Where(x => (x.PipeLineMat.Number ?? 0) > 0).ToList();
|
|
|
|
var materialCodes = pipeLineMats
|
|
.Where(x => !string.IsNullOrEmpty(x.PipeLineMat.MaterialCode))
|
|
.Select(x => x.PipeLineMat.MaterialCode)
|
|
.Distinct()
|
|
.ToList();
|
|
var materialCode2s = pipeLineMats
|
|
.Where(x => !string.IsNullOrEmpty(x.PipeLineMat.MaterialCode2))
|
|
.Select(x => x.PipeLineMat.MaterialCode2)
|
|
.Distinct()
|
|
.ToList();
|
|
var libByMaterialCode = db.HJGL_MaterialCodeLib
|
|
.Where(x => materialCodes.Contains(x.MaterialCode))
|
|
.ToList()
|
|
.GroupBy(x => x.MaterialCode)
|
|
.ToDictionary(x => x.Key, x => x.First());
|
|
var libByCode = db.HJGL_MaterialCodeLib
|
|
.Where(x => materialCode2s.Contains(x.Code))
|
|
.ToList()
|
|
.GroupBy(x => x.Code)
|
|
.ToDictionary(x => x.Key, x => x.First());
|
|
|
|
var requiredMaterials = pipeLineMats.Select(x =>
|
|
{
|
|
HJGL_MaterialCodeLib lib = null;
|
|
// 已反写材料主编码时,优先按 MaterialCode 精确取材料库信息。
|
|
if (!string.IsNullOrEmpty(x.PipeLineMat.MaterialCode) && libByMaterialCode.ContainsKey(x.PipeLineMat.MaterialCode))
|
|
{
|
|
lib = libByMaterialCode[x.PipeLineMat.MaterialCode];
|
|
}
|
|
// 未反写时只能按导入材料编码 Code 找候选材料库。
|
|
else if (!string.IsNullOrEmpty(x.PipeLineMat.MaterialCode2) && libByCode.ContainsKey(x.PipeLineMat.MaterialCode2))
|
|
{
|
|
lib = libByCode[x.PipeLineMat.MaterialCode2];
|
|
}
|
|
|
|
string code = !string.IsNullOrEmpty(x.PipeLineMat.MaterialCode2) ? x.PipeLineMat.MaterialCode2 : lib?.Code;
|
|
return new Tw_PipeMatMatchOutput
|
|
{
|
|
Id = Guid.NewGuid().ToString(),
|
|
PipeLineMatId = x.PipeLineMat.PipeLineMatId,
|
|
PipelineId = x.PipeLineMat.PipelineId,
|
|
PipelineCode = x.PipelineCode,
|
|
UnitWorkId = x.UnitWorkId,
|
|
UnitWorkName = x.UnitWorkName,
|
|
PrefabricatedComponents = x.PipeLineMat.PrefabricatedComponents,
|
|
WeldJointId = x.PipeLineMat.WeldJointId,
|
|
WeldJointCode = x.WeldJoint == null ? null : x.WeldJoint.WeldJointCode,
|
|
MaterialCode = code,
|
|
MatchMaterialCode = x.PipeLineMat.MaterialCode,
|
|
Code = code,
|
|
HeatNo = lib?.HeatNo,
|
|
BatchNo = lib?.BatchNo,
|
|
MaterialName = lib?.MaterialName,
|
|
MaterialSpec = lib?.MaterialSpec,
|
|
MaterialUnit = lib?.MaterialUnit,
|
|
MaterialDef = lib?.MaterialDef,
|
|
NeedNum = x.PipeLineMat.Number,
|
|
};
|
|
}).ToList();
|
|
|
|
var orderedPipelineMaterials = new Dictionary<string, List<Tw_PipeMatMatchOutput>>();
|
|
foreach (string id in pipelineIds)
|
|
{
|
|
orderedPipelineMaterials[id] = requiredMaterials
|
|
.Where(x => x.PipelineId == id)
|
|
.OrderBy(x => x.PrefabricatedComponents)
|
|
.ThenBy(x => x.WeldJointCode)
|
|
.ThenBy(x => x.MaterialCode)
|
|
.ThenBy(x => x.PipeLineMatId)
|
|
.ToList();
|
|
}
|
|
|
|
var newRequiredMaterials = new List<Tw_PipeMatMatchOutput>();
|
|
var addedMaterialIds = new HashSet<string>();
|
|
|
|
// 先处理全部管线的手动优先焊口,保证人工选择始终高于任何自动优先规则。
|
|
foreach (string id in pipelineIds)
|
|
{
|
|
if (priorityWeldJoints != null && priorityWeldJoints.ContainsKey(id) && priorityWeldJoints[id] != null && priorityWeldJoints[id].Any())
|
|
{
|
|
var weldJointIds = priorityWeldJoints[id];
|
|
var manualPriorityMaterials = orderedPipelineMaterials[id]
|
|
.Where(x => weldJointIds.Contains(x.WeldJointId))
|
|
.OrderBy(x => weldJointIds.IndexOf(x.WeldJointId))
|
|
.ThenBy(x => x.PrefabricatedComponents)
|
|
.ThenBy(x => x.WeldJointCode)
|
|
.ThenBy(x => x.MaterialCode)
|
|
.ToList();
|
|
newRequiredMaterials.AddRange(manualPriorityMaterials);
|
|
foreach (var item in manualPriorityMaterials)
|
|
{
|
|
addedMaterialIds.Add(item.PipeLineMatId);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 再处理全部续作组件,避免前一条管线的未开工组件抢占后一条管线续作组件的库存。
|
|
foreach (string id in pipelineIds)
|
|
{
|
|
var continuationMaterials = orderedPipelineMaterials[id]
|
|
.Where(x => !addedMaterialIds.Contains(x.PipeLineMatId)
|
|
&& continuationComponentKeys.Contains(GetComponentKey(x.PipelineId, x.PrefabricatedComponents)))
|
|
.ToList();
|
|
newRequiredMaterials.AddRange(continuationMaterials);
|
|
foreach (var item in continuationMaterials)
|
|
{
|
|
addedMaterialIds.Add(item.PipeLineMatId);
|
|
}
|
|
}
|
|
|
|
// 最后处理所有尚未开工组件,保持管线及组件内的稳定排序。
|
|
foreach (string id in pipelineIds)
|
|
{
|
|
newRequiredMaterials.AddRange(orderedPipelineMaterials[id].Where(x => !addedMaterialIds.Contains(x.PipeLineMatId)));
|
|
}
|
|
|
|
results = GetMatMatchOutput(newRequiredMaterials, warehouseCode, projectId, true);
|
|
// 组件匹配率以当前区域剩余未焊口的材料需求为口径,并回填到每条明细供表格合并展示。
|
|
foreach (var componentGroup in results.GroupBy(x => new { x.PipelineId, x.PrefabricatedComponents }))
|
|
{
|
|
decimal needNum = componentGroup.Sum(x => x.NeedNum) ?? 0;
|
|
decimal matchNum = componentGroup.Sum(x => x.MatchNum) ?? 0;
|
|
decimal componentMatchRate = needNum > 0 ? matchNum / needNum : 0;
|
|
string componentMatchRateString = Math.Round(componentMatchRate * 100, 2).ToString() + "%";
|
|
foreach (var item in componentGroup)
|
|
{
|
|
item.ComponentMatchRate = componentMatchRate;
|
|
item.ComponentMatchRateString = componentMatchRateString;
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取单位工程下当前区域内同时存在已焊口和未焊口的组件汇总。
|
|
/// </summary>
|
|
public static List<Tw_PartialWeldedComponentOutput> GetPartialWeldedComponents(string projectId, string unitWorkId, string pipeArea, string warehouseCode)
|
|
{
|
|
string jointAttribute = GetJointAttributeByPipeArea(pipeArea);
|
|
if (string.IsNullOrEmpty(projectId) || string.IsNullOrEmpty(unitWorkId) || string.IsNullOrEmpty(jointAttribute))
|
|
{
|
|
return new List<Tw_PartialWeldedComponentOutput>();
|
|
}
|
|
|
|
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
|
|
{
|
|
var componentWeldRows = (from x in db.HJGL_PipeLineMat
|
|
join z in db.HJGL_Pipeline on x.PipelineId equals z.PipelineId
|
|
join m in db.WBS_UnitWork on z.UnitWorkId equals m.UnitWorkId
|
|
join w in db.HJGL_WeldJoint on x.WeldJointId equals w.WeldJointId
|
|
where z.ProjectId == projectId && z.UnitWorkId == unitWorkId
|
|
&& x.PipeArea == pipeArea
|
|
&& x.PrefabricatedComponents != null && x.PrefabricatedComponents != ""
|
|
&& w.JointAttribute == jointAttribute
|
|
select new
|
|
{
|
|
z.PipelineId,
|
|
z.PipelineCode,
|
|
z.UnitWorkId,
|
|
m.UnitWorkName,
|
|
x.PrefabricatedComponents,
|
|
w.WeldJointId,
|
|
w.WeldingDailyId
|
|
}).ToList();
|
|
|
|
var partialComponents = componentWeldRows
|
|
.GroupBy(x => new { x.PipelineId, x.PipelineCode, x.UnitWorkId, x.UnitWorkName, x.PrefabricatedComponents })
|
|
.Select(group =>
|
|
{
|
|
var weldJoints = group.GroupBy(x => x.WeldJointId).Select(x => x.First()).ToList();
|
|
int weldedCount = weldJoints.Count(x => !string.IsNullOrEmpty(x.WeldingDailyId));
|
|
int totalCount = weldJoints.Count;
|
|
return new Tw_PartialWeldedComponentOutput
|
|
{
|
|
UnitWorkId = group.Key.UnitWorkId,
|
|
UnitWorkName = group.Key.UnitWorkName,
|
|
PipelineId = group.Key.PipelineId,
|
|
PipelineCode = group.Key.PipelineCode,
|
|
PrefabricatedComponents = group.Key.PrefabricatedComponents,
|
|
PipeArea = pipeArea,
|
|
PipeAreaText = pipeArea == PipelineService.PipeArea_SHOP ? "工厂预制" : "现场安装",
|
|
TotalWeldJointCount = totalCount,
|
|
WeldedWeldJointCount = weldedCount,
|
|
UnweldedWeldJointCount = totalCount - weldedCount
|
|
};
|
|
})
|
|
.Where(x => x.WeldedWeldJointCount > 0 && x.UnweldedWeldJointCount > 0)
|
|
.OrderBy(x => x.PipelineCode)
|
|
.ThenBy(x => x.PrefabricatedComponents)
|
|
.ToList();
|
|
|
|
if (!partialComponents.Any())
|
|
{
|
|
return partialComponents;
|
|
}
|
|
|
|
// 导出匹配率复用页面匹配规则,保证区域、未焊口及续作组件优先级完全一致。
|
|
var pipelineIds = partialComponents.Select(x => x.PipelineId).Distinct().ToList();
|
|
var matchOutputs = GetPipeMatMatch(projectId, pipelineIds, warehouseCode, null, pipeArea);
|
|
var componentRates = matchOutputs
|
|
.GroupBy(x => GetComponentKey(x.PipelineId, x.PrefabricatedComponents))
|
|
.ToDictionary(x => x.Key, x => x.First().ComponentMatchRate ?? 0);
|
|
foreach (var component in partialComponents)
|
|
{
|
|
decimal componentRate;
|
|
componentRates.TryGetValue(GetComponentKey(component.PipelineId, component.PrefabricatedComponents), out componentRate);
|
|
component.ComponentMatchRate = componentRate;
|
|
component.ComponentMatchRateString = Math.Round(componentRate * 100, 2).ToString() + "%";
|
|
}
|
|
|
|
return partialComponents;
|
|
}
|
|
}
|
|
|
|
private static string GetJointAttributeByPipeArea(string pipeArea)
|
|
{
|
|
if (pipeArea == PipelineService.PipeArea_SHOP)
|
|
{
|
|
return "预制口";
|
|
}
|
|
if (pipeArea == PipelineService.PipeArea_FIELD)
|
|
{
|
|
return "安装口";
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static string GetComponentKey(string pipelineId, string componentCode)
|
|
{
|
|
return (pipelineId ?? string.Empty) + "\u001f" + (componentCode ?? string.Empty);
|
|
}
|
|
/// <summary>
|
|
/// 根据管线材料匹配结果,获取管线匹配率
|
|
/// </summary>
|
|
/// <param name="twPipeMatMatch"></param>
|
|
/// <returns></returns>
|
|
public static List<Tw_PipeMatchOutput> GetPipeMatch(List<Tw_PipeMatMatchOutput> 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;
|
|
}
|
|
|
|
}
|
|
|
|
}
|