using System; using System.Collections.Generic; using System.Data; using Microsoft.Data.SqlClient; namespace XLAB2 { internal sealed class VerificationReportsService { private const string ReportSourceSql = @" FROM dbo.EKZMK m JOIN dbo.EKZ z ON z.IDEKZ = m.IDEKZ LEFT JOIN dbo.TPRZ tprz ON tprz.IDTPRZ = z.IDTPRZ LEFT JOIN dbo.TIPS tips ON tips.IDTIPS = tprz.IDTIPS LEFT JOIN dbo.SPOI areas ON areas.IDSPOI = tips.IDSPOI LEFT JOIN dbo.FRPD customers ON customers.IDFRPD = z.IDFRPDV WHERE m.DTMKFK IS NOT NULL AND (@DateFrom IS NULL OR m.DTMKFK >= @DateFrom) AND (@DateToExclusive IS NULL OR m.DTMKFK < @DateToExclusive) AND (@CustomerId IS NULL OR z.IDFRPDV = @CustomerId) AND (@MeasurementAreaId IS NULL OR tips.IDSPOI = @MeasurementAreaId)"; public VerificationReportData LoadReport(VerificationReportFilter filter) { var normalizedFilter = NormalizeFilter(filter); using (var connection = ReferenceDirectorySqlHelpers.CreateConnection()) { connection.Open(); return new VerificationReportData { Summary = LoadSummary(connection, normalizedFilter), CustomerRows = LoadCustomerRows(connection, normalizedFilter), MeasurementAreaRows = LoadMeasurementAreaRows(connection, normalizedFilter) }; } } public IReadOnlyList LoadCustomerItems() { return ReferenceDirectorySqlHelpers.LoadLookupItems(@" SELECT DISTINCT customers.IDFRPD AS Id, customers.NMFRPD AS Name FROM dbo.EKZMK m JOIN dbo.EKZ z ON z.IDEKZ = m.IDEKZ JOIN dbo.FRPD customers ON customers.IDFRPD = z.IDFRPDV WHERE m.DTMKFK IS NOT NULL AND NULLIF(LTRIM(RTRIM(customers.NMFRPD)), N'') IS NOT NULL ORDER BY customers.NMFRPD, customers.IDFRPD;"); } public IReadOnlyList LoadMeasurementAreaItems() { return ReferenceDirectorySqlHelpers.LoadLookupItems(@" SELECT DISTINCT areas.IDSPOI AS Id, areas.NMOI AS Name FROM dbo.EKZMK m JOIN dbo.EKZ z ON z.IDEKZ = m.IDEKZ LEFT JOIN dbo.TPRZ tprz ON tprz.IDTPRZ = z.IDTPRZ LEFT JOIN dbo.TIPS tips ON tips.IDTIPS = tprz.IDTIPS JOIN dbo.SPOI areas ON areas.IDSPOI = tips.IDSPOI WHERE m.DTMKFK IS NOT NULL AND NULLIF(LTRIM(RTRIM(areas.NMOI)), N'') IS NOT NULL ORDER BY areas.NMOI, areas.IDSPOI;"); } private static void AddFilterParameters(SqlCommand command, VerificationReportFilter filter) { command.CommandTimeout = ReferenceDirectorySqlHelpers.GetCommandTimeoutSeconds(); ReferenceDirectorySqlHelpers.AddNullableIntParameter(command, "@CustomerId", filter.CustomerId); ReferenceDirectorySqlHelpers.AddNullableIntParameter(command, "@MeasurementAreaId", filter.MeasurementAreaId); ReferenceDirectorySqlHelpers.AddNullableDateTimeParameter(command, "@DateFrom", filter.DateFrom); ReferenceDirectorySqlHelpers.AddNullableDateTimeParameter(command, "@DateToExclusive", GetDateToExclusive(filter.DateTo)); } private static DateTime? GetDateToExclusive(DateTime? dateTo) { return dateTo.HasValue ? dateTo.Value.Date.AddDays(1) : (DateTime?)null; } private static VerificationReportSummary LoadSummary(SqlConnection connection, VerificationReportFilter filter) { var sql = @" SELECT COUNT(*) AS TotalCount, COALESCE(SUM(CASE WHEN m.GDN = 1 THEN 1 ELSE 0 END), 0) AS GoodCount, COALESCE(SUM(CASE WHEN m.GDN = 0 THEN 1 ELSE 0 END), 0) AS RejectedCount, COALESCE(SUM(CASE WHEN m.GDN IS NULL THEN 1 ELSE 0 END), 0) AS WithoutResultCount, COALESCE(SUM(CASE WHEN m.DTVDM IS NOT NULL THEN 1 ELSE 0 END), 0) AS IssuedCount " + ReportSourceSql + ";"; using (var command = new SqlCommand(sql, connection)) { AddFilterParameters(command, filter); using (var reader = command.ExecuteReader()) { if (!reader.Read()) { return new VerificationReportSummary(); } return new VerificationReportSummary { TotalCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "TotalCount"), GoodCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "GoodCount"), RejectedCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "RejectedCount"), WithoutResultCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "WithoutResultCount"), IssuedCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "IssuedCount") }; } } } private static IReadOnlyList LoadCustomerRows(SqlConnection connection, VerificationReportFilter filter) { var sql = @" SELECT z.IDFRPDV AS CustomerId, COALESCE(NULLIF(LTRIM(RTRIM(customers.NMFRPD)), N''), N'Не указано') AS CustomerName, COUNT(*) AS TotalCount, COALESCE(SUM(CASE WHEN m.GDN = 1 THEN 1 ELSE 0 END), 0) AS GoodCount, COALESCE(SUM(CASE WHEN m.GDN = 0 THEN 1 ELSE 0 END), 0) AS RejectedCount, COALESCE(SUM(CASE WHEN m.GDN IS NULL THEN 1 ELSE 0 END), 0) AS WithoutResultCount, COALESCE(SUM(CASE WHEN m.DTVDM IS NOT NULL THEN 1 ELSE 0 END), 0) AS IssuedCount " + ReportSourceSql + @" GROUP BY z.IDFRPDV, COALESCE(NULLIF(LTRIM(RTRIM(customers.NMFRPD)), N''), N'Не указано') ORDER BY CustomerName;"; var rows = new List(); using (var command = new SqlCommand(sql, connection)) { AddFilterParameters(command, filter); using (var reader = command.ExecuteReader()) { while (reader.Read()) { rows.Add(new VerificationReportCustomerRow { CustomerId = ReferenceDirectorySqlHelpers.GetNullableInt32(reader, "CustomerId"), CustomerName = ReferenceDirectorySqlHelpers.GetString(reader, "CustomerName"), TotalCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "TotalCount"), GoodCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "GoodCount"), RejectedCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "RejectedCount"), WithoutResultCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "WithoutResultCount"), IssuedCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "IssuedCount") }); } } } return rows; } private static IReadOnlyList LoadMeasurementAreaRows(SqlConnection connection, VerificationReportFilter filter) { var sql = @" SELECT tips.IDSPOI AS MeasurementAreaId, COALESCE(NULLIF(LTRIM(RTRIM(areas.NMOI)), N''), N'Не указано') AS MeasurementAreaName, COUNT(*) AS TotalCount, COALESCE(SUM(CASE WHEN m.GDN = 1 THEN 1 ELSE 0 END), 0) AS GoodCount, COALESCE(SUM(CASE WHEN m.GDN = 0 THEN 1 ELSE 0 END), 0) AS RejectedCount, COALESCE(SUM(CASE WHEN m.GDN IS NULL THEN 1 ELSE 0 END), 0) AS WithoutResultCount, COALESCE(SUM(CASE WHEN m.DTVDM IS NOT NULL THEN 1 ELSE 0 END), 0) AS IssuedCount " + ReportSourceSql + @" GROUP BY tips.IDSPOI, COALESCE(NULLIF(LTRIM(RTRIM(areas.NMOI)), N''), N'Не указано') ORDER BY MeasurementAreaName;"; var rows = new List(); using (var command = new SqlCommand(sql, connection)) { AddFilterParameters(command, filter); using (var reader = command.ExecuteReader()) { while (reader.Read()) { rows.Add(new VerificationReportMeasurementAreaRow { MeasurementAreaId = ReferenceDirectorySqlHelpers.GetNullableInt32(reader, "MeasurementAreaId"), MeasurementAreaName = ReferenceDirectorySqlHelpers.GetString(reader, "MeasurementAreaName"), TotalCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "TotalCount"), GoodCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "GoodCount"), RejectedCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "RejectedCount"), WithoutResultCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "WithoutResultCount"), IssuedCount = ReferenceDirectorySqlHelpers.GetInt32(reader, "IssuedCount") }); } } } return rows; } private static VerificationReportFilter NormalizeFilter(VerificationReportFilter filter) { var normalizedFilter = filter ?? new VerificationReportFilter(); var dateFrom = normalizedFilter.DateFrom.HasValue ? normalizedFilter.DateFrom.Value.Date : (DateTime?)null; var dateTo = normalizedFilter.DateTo.HasValue ? normalizedFilter.DateTo.Value.Date : (DateTime?)null; if (dateFrom.HasValue && dateTo.HasValue && dateFrom.Value > dateTo.Value) { throw new InvalidOperationException("Дата \"с\" не может быть позже даты \"по\"."); } return new VerificationReportFilter { CustomerId = normalizedFilter.CustomerId, MeasurementAreaId = normalizedFilter.MeasurementAreaId, DateFrom = dateFrom, DateTo = dateTo }; } } }