This commit is contained in:
Курнат Андрей
2026-03-23 19:56:35 +03:00
parent d54f5b8e22
commit bf9f54f91c
226 changed files with 3250 additions and 33 deletions

BIN
XLAB2/ClosePsv.docx Normal file

Binary file not shown.

View File

@@ -325,7 +325,7 @@
Margin="12,0,0,0" Margin="12,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="DimGray" Foreground="DimGray"
Text="Поиск по типу, диапазону, госреестру или зав. №" /> Text="Поиск по наименованию, типу, диапазону, госреестру или зав. №" />
</Grid> </Grid>
<DataGrid Grid.Row="1" <DataGrid Grid.Row="1"
@@ -363,11 +363,15 @@
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
<DataGridTextColumn Header="Наименование"
Width="220"
Binding="{Binding InstrumentName}" />
<DataGridTextColumn Header="Тип" <DataGridTextColumn Header="Тип"
Width="180" Width="160"
Binding="{Binding InstrumentType}" /> Binding="{Binding InstrumentType}" />
<DataGridTextColumn Header="Диапазон" <DataGridTextColumn Header="Диапазон"
Width="170" Width="160"
Binding="{Binding RangeText}" /> Binding="{Binding RangeText}" />
<DataGridTextColumn Header="Госреестр" <DataGridTextColumn Header="Госреестр"
Width="120" Width="120"

View File

@@ -501,6 +501,23 @@ namespace XLAB2
return serialNumbers.Count == 0 ? string.Empty : string.Join(", ", serialNumbers.ToArray()); return serialNumbers.Count == 0 ? string.Empty : string.Join(", ", serialNumbers.ToArray());
} }
private static string BuildInstrumentNamesText(IEnumerable<PsvDocumentLine> lines)
{
var instrumentNames = (lines ?? Enumerable.Empty<PsvDocumentLine>())
.Select(delegate(PsvDocumentLine line)
{
return line == null || string.IsNullOrWhiteSpace(line.InstrumentName)
? null
: line.InstrumentName.Trim();
})
.Where(delegate(string instrumentName) { return !string.IsNullOrWhiteSpace(instrumentName); })
.Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(delegate(string instrumentName) { return instrumentName; }, StringComparer.OrdinalIgnoreCase)
.ToList();
return instrumentNames.Count == 0 ? string.Empty : string.Join("; ", instrumentNames.ToArray());
}
private static bool HasVerificationData(PsvDocumentLine line) private static bool HasVerificationData(PsvDocumentLine line)
{ {
return line != null return line != null
@@ -1759,7 +1776,8 @@ namespace XLAB2
return true; return true;
} }
return Contains(group.InstrumentType, GroupFilterText) return Contains(group.InstrumentName, GroupFilterText)
|| Contains(group.InstrumentType, GroupFilterText)
|| Contains(group.RangeText, GroupFilterText) || Contains(group.RangeText, GroupFilterText)
|| Contains(group.RegistryNumber, GroupFilterText) || Contains(group.RegistryNumber, GroupFilterText)
|| Contains(group.SerialNumbersText, GroupFilterText); || Contains(group.SerialNumbersText, GroupFilterText);
@@ -2330,6 +2348,7 @@ namespace XLAB2
.ThenBy(group => group.Key.RangeText) .ThenBy(group => group.Key.RangeText)
.Select(group => new PsvDocumentGroupSummary .Select(group => new PsvDocumentGroupSummary
{ {
InstrumentName = BuildInstrumentNamesText(group),
InstrumentType = group.Key.InstrumentType, InstrumentType = group.Key.InstrumentType,
RangeText = group.Key.RangeText, RangeText = group.Key.RangeText,
RegistryNumber = group.Key.RegistryNumber, RegistryNumber = group.Key.RegistryNumber,

BIN
XLAB2/OpenPsv.docx Normal file

Binary file not shown.

View File

@@ -347,6 +347,8 @@ namespace XLAB2
{ {
private bool _isBatchSelected; private bool _isBatchSelected;
public string InstrumentName { get; set; }
public string InstrumentType { get; set; } public string InstrumentType { get; set; }
public string RangeText { get; set; } public string RangeText { get; set; }

View File

@@ -9,6 +9,8 @@ namespace XLAB2
{ {
internal sealed class PsvPrintService internal sealed class PsvPrintService
{ {
private const int OpenPsvTableColumnCount = 7;
private const int ClosePsvTableColumnCount = 12;
private const int PrintDialogId = 88; private const int PrintDialogId = 88;
private const int WordAlertsNone = 0; private const int WordAlertsNone = 0;
private const int WordCloseDoNotSaveChanges = 0; private const int WordCloseDoNotSaveChanges = 0;
@@ -165,7 +167,7 @@ namespace XLAB2
ReplacePlaceholder(document, "next", FormatDate(dueDate)); ReplacePlaceholder(document, "next", FormatDate(dueDate));
} }
FillTable(document, groupedLines); FillTable(document, groupedLines, summary.IssuedOn.HasValue);
} }
private static void PopulateVerificationTemplate(dynamic document, PsvDocumentLine line) private static void PopulateVerificationTemplate(dynamic document, PsvDocumentLine line)
@@ -187,13 +189,14 @@ namespace XLAB2
ReplacePlaceholder(document, "date", FormatDate(verificationDate)); ReplacePlaceholder(document, "date", FormatDate(verificationDate));
} }
private static void FillTable(dynamic document, IReadOnlyList<PrintedGroupRow> rowsToPrint) private static void FillTable(dynamic document, IReadOnlyList<PrintedGroupRow> rowsToPrint, bool isClosedDocument)
{ {
dynamic table = null; dynamic table = null;
try try
{ {
table = document.Tables.Item(1); table = document.Tables.Item(1);
EnsurePsvTableLayout(table, isClosedDocument ? ClosePsvTableColumnCount : OpenPsvTableColumnCount);
for (var index = 0; index < rowsToPrint.Count; index++) for (var index = 0; index < rowsToPrint.Count; index++)
{ {
@@ -209,9 +212,20 @@ namespace XLAB2
SetCellText(row, 4, rowData.RangeText, false); SetCellText(row, 4, rowData.RangeText, false);
SetCellText(row, 5, rowData.SerialNumberText, false); SetCellText(row, 5, rowData.SerialNumberText, false);
SetCellText(row, 6, rowData.GroupCount.ToString(CultureInfo.InvariantCulture), true); SetCellText(row, 6, rowData.GroupCount.ToString(CultureInfo.InvariantCulture), true);
SetCellText(row, 7, rowData.PassedCount > 0 ? rowData.PassedCount.ToString(CultureInfo.InvariantCulture) : string.Empty, true);
SetCellText(row, 8, rowData.FailedCount > 0 ? rowData.FailedCount.ToString(CultureInfo.InvariantCulture) : string.Empty, true); if (isClosedDocument)
SetCellText(row, 9, rowData.Notes, false); {
SetCellText(row, 7, rowData.PassedCount > 0 ? rowData.PassedCount.ToString(CultureInfo.InvariantCulture) : string.Empty, true);
SetCellText(row, 8, rowData.FailedCount > 0 ? rowData.FailedCount.ToString(CultureInfo.InvariantCulture) : string.Empty, true);
SetCellText(row, 9, rowData.VerificationDocumentText, false);
SetCellText(row, 10, rowData.StickerNumberText, false);
SetCellText(row, 11, rowData.VerifierNameText, false);
SetCellText(row, 12, rowData.Notes, false);
}
else
{
SetCellText(row, 7, rowData.Notes, false);
}
} }
finally finally
{ {
@@ -225,6 +239,35 @@ namespace XLAB2
} }
} }
private static void EnsurePsvTableLayout(dynamic table, int expectedColumnCount)
{
if (table == null)
{
throw new InvalidOperationException("В шаблоне ПСВ не найдена таблица для печати.");
}
var actualColumnCount = 0;
try
{
actualColumnCount = Convert.ToInt32(table.Columns.Count, CultureInfo.InvariantCulture);
}
catch (Exception ex)
{
throw new InvalidOperationException("Не удалось определить структуру таблицы шаблона ПСВ.", ex);
}
if (actualColumnCount != expectedColumnCount)
{
throw new InvalidOperationException(
string.Format(
CultureInfo.InvariantCulture,
"Шаблон ПСВ имеет неверную структуру таблицы: ожидается {0} колонок, найдено {1}.",
expectedColumnCount,
actualColumnCount));
}
}
private static void SetCellText(dynamic row, int columnIndex, string value, bool centerAlign) private static void SetCellText(dynamic row, int columnIndex, string value, bool centerAlign)
{ {
dynamic cell = null; dynamic cell = null;
@@ -274,7 +317,7 @@ namespace XLAB2
} }
} }
private static IReadOnlyList<PrintedGroupRow> BuildPrintedGroups(IEnumerable<PsvDocumentLine> lines, bool includeClosedNotes) private static IReadOnlyList<PrintedGroupRow> BuildPrintedGroups(IEnumerable<PsvDocumentLine> lines, bool includeClosedDetails)
{ {
return (lines ?? Enumerable.Empty<PsvDocumentLine>()) return (lines ?? Enumerable.Empty<PsvDocumentLine>())
.GroupBy(delegate(PsvDocumentLine line) .GroupBy(delegate(PsvDocumentLine line)
@@ -302,7 +345,10 @@ namespace XLAB2
GroupCount = materializedLines.Count, GroupCount = materializedLines.Count,
PassedCount = materializedLines.Count(delegate(PsvDocumentLine line) { return line.IsPassed == true; }), PassedCount = materializedLines.Count(delegate(PsvDocumentLine line) { return line.IsPassed == true; }),
FailedCount = materializedLines.Count(delegate(PsvDocumentLine line) { return line.IsPassed == false; }), FailedCount = materializedLines.Count(delegate(PsvDocumentLine line) { return line.IsPassed == false; }),
Notes = includeClosedNotes ? BuildClosedNotesText(materializedLines) : string.Empty VerificationDocumentText = includeClosedDetails ? BuildVerificationDocumentText(materializedLines) : string.Empty,
StickerNumberText = includeClosedDetails ? BuildStickerNumberText(materializedLines) : string.Empty,
VerifierNameText = includeClosedDetails ? BuildVerifierNameText(materializedLines) : string.Empty,
Notes = BuildNotesText(materializedLines)
}; };
}) })
.ToList(); .ToList();
@@ -340,35 +386,44 @@ namespace XLAB2
return string.Join(", ", serialNumbers.ToArray()); return string.Join(", ", serialNumbers.ToArray());
} }
private static string BuildClosedNotesText(IReadOnlyList<PsvDocumentLine> lines) private static string BuildNotesText(IReadOnlyList<PsvDocumentLine> lines)
{ {
var parts = new List<string>(); return string.Join("; ", lines
.Select(delegate(PsvDocumentLine line) { return NormalizeText(line == null ? null : line.Notes); })
.Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); })
.Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(delegate(string value) { return value; }, StringComparer.OrdinalIgnoreCase)
.ToArray());
}
var verificationDocuments = lines private static string BuildVerificationDocumentText(IReadOnlyList<PsvDocumentLine> lines)
{
return string.Join("; ", lines
.Select(FormatVerificationDocument) .Select(FormatVerificationDocument)
.Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); }) .Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); })
.Distinct(StringComparer.OrdinalIgnoreCase) .Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(delegate(string value) { return value; }, StringComparer.OrdinalIgnoreCase) .OrderBy(delegate(string value) { return value; }, StringComparer.OrdinalIgnoreCase)
.ToList(); .ToArray());
}
if (verificationDocuments.Count > 0) private static string BuildStickerNumberText(IReadOnlyList<PsvDocumentLine> lines)
{ {
parts.Add("Документы: " + string.Join("; ", verificationDocuments.ToArray())); return string.Join(", ", lines
} .Select(delegate(PsvDocumentLine line) { return NormalizeText(line == null ? null : line.StickerNumber); })
var stickerNumbers = lines
.Select(delegate(PsvDocumentLine line) { return NormalizeText(line.StickerNumber); })
.Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); }) .Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); })
.Distinct(StringComparer.OrdinalIgnoreCase) .Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(delegate(string value) { return value; }, StringComparer.OrdinalIgnoreCase) .OrderBy(delegate(string value) { return value; }, StringComparer.OrdinalIgnoreCase)
.ToList(); .ToArray());
}
if (stickerNumbers.Count > 0) private static string BuildVerifierNameText(IReadOnlyList<PsvDocumentLine> lines)
{ {
parts.Add("Наклейки: " + string.Join(", ", stickerNumbers.ToArray())); return string.Join("; ", lines
} .Select(delegate(PsvDocumentLine line) { return NormalizeText(line == null ? null : line.VerifierName); })
.Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); })
return string.Join(". ", parts.ToArray()); .Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(delegate(string value) { return value; }, StringComparer.OrdinalIgnoreCase)
.ToArray());
} }
private static string FormatVerificationDocument(PsvDocumentLine line) private static string FormatVerificationDocument(PsvDocumentLine line)
@@ -445,6 +500,7 @@ namespace XLAB2
var candidates = new[] var candidates = new[]
{ {
Path.Combine(baseDirectory, fileName), Path.Combine(baseDirectory, fileName),
Path.GetFullPath(Path.Combine(baseDirectory, "..", fileName)),
Path.GetFullPath(Path.Combine(baseDirectory, "..", "..", fileName)), Path.GetFullPath(Path.Combine(baseDirectory, "..", "..", fileName)),
Path.GetFullPath(Path.Combine(baseDirectory, "..", "..", "..", fileName)) Path.GetFullPath(Path.Combine(baseDirectory, "..", "..", "..", fileName))
}; };
@@ -551,6 +607,12 @@ namespace XLAB2
public string RangeText { get; set; } public string RangeText { get; set; }
public string SerialNumberText { get; set; } public string SerialNumberText { get; set; }
public string StickerNumberText { get; set; }
public string VerificationDocumentText { get; set; }
public string VerifierNameText { get; set; }
} }
private sealed class PrintGroupKey : IEquatable<PrintGroupKey> private sealed class PrintGroupKey : IEquatable<PrintGroupKey>

View File

@@ -23,16 +23,14 @@
<Content Include="appsettings.json"> <Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="..\ClosePsv.docx"> <Content Include="ClosePsv.docx">
<Link>ClosePsv.docx</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="..\Izv.docx"> <Content Include="..\Izv.docx">
<Link>Izv.docx</Link> <Link>Izv.docx</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="..\OpenPsv.docx"> <Content Include="OpenPsv.docx">
<Link>OpenPsv.docx</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="..\Svid.docx"> <Content Include="..\Svid.docx">

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,19 @@
{
"runtimeOptions": {
"tfm": "net10.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "10.0.0"
},
{
"name": "Microsoft.WindowsDesktop.App",
"version": "10.0.0"
}
],
"configProperties": {
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
"CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": false
}
}
}

View File

@@ -0,0 +1,18 @@
{
"Database": {
"ApplicationName": "XLAB2",
"CommandTimeoutSeconds": 60,
"ConnectRetryCount": 3,
"ConnectRetryIntervalSeconds": 10,
"ConnectTimeoutSeconds": 15,
"Database": "ASUMS",
"Encrypt": false,
"IntegratedSecurity": true,
"MultipleActiveResultSets": true,
"Pooling": true,
"MaxPoolSize": 100,
"MinPoolSize": 0,
"Server": "SEVENHILL\\SQLEXPRESS",
"TrustServerCertificate": true
}
}

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More