Files
XLAB/XLAB2/VerificationReportsService.cs
Курнат Андрей 7bbca6ba55 edit
2026-03-22 21:44:29 +03:00

229 lines
9.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<DirectoryLookupItem> 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<DirectoryLookupItem> 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<VerificationReportCustomerRow> 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<VerificationReportCustomerRow>();
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<VerificationReportMeasurementAreaRow> 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<VerificationReportMeasurementAreaRow>();
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
};
}
}
}