using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; namespace BLL { /// /// 管道预制汇总服务。 /// public static class PipePrefabricationSummaryService { /// /// 按单位、单位工程汇总管道预制达因。 /// public static List GetSummary( string projectId, IEnumerable unitWorkIds, DateTime startDate, DateTime endDate, DateTime reportDate) { if (string.IsNullOrWhiteSpace(projectId)) { throw new ArgumentException("项目不能为空。", "projectId"); } if (startDate.Date > endDate.Date) { throw new ArgumentException("开始日期不能晚于结束日期。"); } var selectedUnitWorkIds = (unitWorkIds ?? Enumerable.Empty()) .Where(x => !string.IsNullOrWhiteSpace(x) && x != Const._Null) .Distinct() .ToList(); var parameters = new List { new SqlParameter("@ProjectId", projectId), new SqlParameter("@StartDate", startDate.Date), // 结束日期按整日包含,SQL 使用小于次日零点规避时间精度问题。 new SqlParameter("@EndDateExclusive", endDate.Date.AddDays(1)), // 报表日期 D 的昨日数据取 D-1,当日零点作为昨日区间的结束边界。 new SqlParameter("@DailyStartDate", reportDate.Date.AddDays(-1)), new SqlParameter("@ReportDate", reportDate.Date) }; string unitWorkFilter = string.Empty; if (selectedUnitWorkIds.Count > 0) { var parameterNames = new List(); for (int index = 0; index < selectedUnitWorkIds.Count; index++) { string parameterName = "@UnitWorkId" + index; parameterNames.Add(parameterName); parameters.Add(new SqlParameter(parameterName, selectedUnitWorkIds[index])); } unitWorkFilter = " AND unitWork.UnitWorkId IN (" + string.Join(",", parameterNames) + ")"; } string sql = @" SELECT ISNULL(unitWork.UnitWorkName, '') AS UnitWorkName, ISNULL(unitInfo.UnitCode, '') AS ConstructionUnitCode, ISNULL(unitWork.UnitWorkCode, '') AS UnitWorkCode, CAST(SUM(ISNULL(joint.Size, 0)) AS DECIMAL(19, 2)) AS TotalDrawingQuantity, CAST(SUM(ISNULL(joint.Size, 0)) AS DECIMAL(19, 2)) AS IsoDrawingQuantity, CAST(SUM(CASE WHEN joint.JointAttribute = N'预制口' THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS WorkFrontQuantity, CAST(SUM(CASE WHEN joint.JointAttribute = N'预制口' AND daily.WeldingDate < @EndDateExclusive THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS CompletedQuantity, CAST(SUM(CASE WHEN joint.JointAttribute = N'预制口' AND daily.WeldingDate >= @StartDate AND daily.WeldingDate < @EndDateExclusive THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS WeeklyQuantity, CAST(SUM(CASE WHEN joint.JointAttribute = N'预制口' AND daily.WeldingDate >= @DailyStartDate AND daily.WeldingDate < @ReportDate THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS DailyQuantity, CAST(SUM(CASE WHEN joint.JointAttribute = N'预制口' AND daily.WeldingDate < @DailyStartDate THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS PreviousDayCumulativeQuantity, CAST(SUM(CASE WHEN joint.JointAttribute = N'预制口' AND daily.WeldingDate < @StartDate THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS LastWeekCumulativeQuantity FROM HJGL_WeldJoint joint INNER JOIN HJGL_Pipeline pipeline ON pipeline.PipelineId = joint.PipelineId INNER JOIN WBS_UnitWork unitWork ON unitWork.UnitWorkId = pipeline.UnitWorkId LEFT JOIN Base_Unit unitInfo ON unitInfo.UnitId = unitWork.UnitId LEFT JOIN HJGL_WeldingDaily daily ON daily.WeldingDailyId = joint.WeldingDailyId WHERE pipeline.ProjectId = @ProjectId AND pipeline.PipeArea = '1'" + unitWorkFilter + @" GROUP BY unitWork.UnitWorkName, unitInfo.UnitCode, unitWork.UnitWorkCode ORDER BY unitWork.UnitWorkName, unitWork.UnitWorkCode"; DataTable table = SQLHelper.GetDataTableRunText(sql, parameters.ToArray()); return table.AsEnumerable().Select((row, index) => { string unitCode; string blockCode; ParseUnitAndBlock( Convert.ToString(row["UnitWorkName"]), Convert.ToString(row["ConstructionUnitCode"]), Convert.ToString(row["UnitWorkCode"]), out unitCode, out blockCode); return new PipePrefabricationSummaryItem { RowKey = (index + 1).ToString(), UnitCode = unitCode, UnitWorkCode = blockCode, // 当前模型没有独立的计划图纸达因字段,图纸总量按工厂预制管线设计焊口总达因统计。 TotalDrawingQuantity = GetDecimal(row, "TotalDrawingQuantity"), IsoDrawingQuantity = GetDecimal(row, "IsoDrawingQuantity"), WorkFrontQuantity = GetDecimal(row, "WorkFrontQuantity"), CompletedQuantity = GetDecimal(row, "CompletedQuantity"), DailyQuantity = GetDecimal(row, "DailyQuantity"), PreviousDayCumulativeQuantity = GetDecimal(row, "PreviousDayCumulativeQuantity"), WeeklyQuantity = GetDecimal(row, "WeeklyQuantity"), LastWeekCumulativeQuantity = GetDecimal(row, "LastWeekCumulativeQuantity"), Note = string.Empty }; }).ToList(); } private static void ParseUnitAndBlock( string unitWorkName, string fallbackUnitCode, string fallbackBlockCode, out string unitCode, out string blockCode) { // 本项目单位工程名称按“Unit.Block”维护,报表需拆分成两个业务列。 string[] segments = (unitWorkName ?? string.Empty).Split(new[] { '.' }, 2); if (segments.Length == 2 && !string.IsNullOrWhiteSpace(segments[0]) && !string.IsNullOrWhiteSpace(segments[1])) { unitCode = segments[0].Trim(); blockCode = segments[1].Trim(); return; } unitCode = fallbackUnitCode ?? string.Empty; blockCode = fallbackBlockCode ?? string.Empty; } private static decimal GetDecimal(DataRow row, string columnName) { return row.IsNull(columnName) ? 0M : Convert.ToDecimal(row[columnName]); } } /// /// 管道预制汇总行。 /// public class PipePrefabricationSummaryItem { public string RowKey { get; set; } public string UnitCode { get; set; } public string UnitWorkCode { get; set; } public decimal TotalDrawingQuantity { get; set; } public decimal IsoDrawingQuantity { get; set; } public decimal WorkFrontQuantity { get; set; } public decimal CompletedQuantity { get; set; } public decimal DailyQuantity { get; set; } public decimal PreviousDayCumulativeQuantity { get; set; } public decimal WeeklyQuantity { get; set; } public decimal LastWeekCumulativeQuantity { get; set; } public string Note { get; set; } public string TotalDrawingQuantityDisplay { get { return FormatQuantity(TotalDrawingQuantity); } } public string IsoDrawingQuantityDisplay { get { return FormatQuantity(IsoDrawingQuantity); } } public string WorkFrontQuantityDisplay { get { return FormatQuantity(WorkFrontQuantity); } } public string CompletedQuantityDisplay { get { return FormatQuantity(CompletedQuantity); } } public string DailyQuantityDisplay { get { return FormatQuantity(DailyQuantity); } } public string PreviousDayCumulativeQuantityDisplay { get { return FormatQuantity(PreviousDayCumulativeQuantity); } } public string WeeklyQuantityDisplay { get { return FormatQuantity(WeeklyQuantity); } } public string LastWeekCumulativeQuantityDisplay { get { return FormatQuantity(LastWeekCumulativeQuantity); } } public string QuantityCompleteRateDisplay { get { return TotalDrawingQuantity <= 0M ? "0.00%" : (CompletedQuantity * 100M / TotalDrawingQuantity).ToString("0.00") + "%"; } } public static string FormatQuantity(decimal quantity) { return quantity.ToString("#,##0.##"); } } }