This commit is contained in:
Курнат Андрей
2026-03-23 21:24:09 +03:00
parent bf9f54f91c
commit 74d793948e
471 changed files with 6560 additions and 22 deletions

View File

@@ -29,6 +29,8 @@ namespace XLAB2
public string InventoryNumber { get; set; } public string InventoryNumber { get; set; }
public string StickerNumbers { get; set; }
public string Notes { get; set; } public string Notes { get; set; }
} }
@@ -48,6 +50,10 @@ namespace XLAB2
public DateTime? VerificationDocumentDate { get; set; } public DateTime? VerificationDocumentDate { get; set; }
public string StickerNumber { get; set; }
public string VerifierName { get; set; }
public int PeriodMonths { get; set; } public int PeriodMonths { get; set; }
public DateTime? AcceptedOn { get; set; } public DateTime? AcceptedOn { get; set; }

View File

@@ -166,6 +166,7 @@ SELECT
ownerOrg.NMFRPD AS OwnerOrganizationName, ownerOrg.NMFRPD AS OwnerOrganizationName,
z.NNZV AS SerialNumber, z.NNZV AS SerialNumber,
z.NNIN AS InventoryNumber, z.NNIN AS InventoryNumber,
stickers.StickerNumbers AS StickerNumbers,
CAST(z.DSEKZ AS nvarchar(max)) AS Notes CAST(z.DSEKZ AS nvarchar(max)) AS Notes
FROM dbo.EKZ z FROM dbo.EKZ z
JOIN dbo.TPRZ tprz ON tprz.IDTPRZ = z.IDTPRZ JOIN dbo.TPRZ tprz ON tprz.IDTPRZ = z.IDTPRZ
@@ -173,6 +174,25 @@ JOIN dbo.TIPS tips ON tips.IDTIPS = tprz.IDTIPS
JOIN dbo.SPNMTP names ON names.IDSPNMTP = tips.IDSPNMTP JOIN dbo.SPNMTP names ON names.IDSPNMTP = tips.IDSPNMTP
JOIN dbo.SPOI areas ON areas.IDSPOI = tips.IDSPOI JOIN dbo.SPOI areas ON areas.IDSPOI = tips.IDSPOI
JOIN dbo.FRPD ownerOrg ON ownerOrg.IDFRPD = z.IDFRPDV JOIN dbo.FRPD ownerOrg ON ownerOrg.IDFRPD = z.IDFRPDV
OUTER APPLY
(
SELECT STUFF(
(
SELECT N' ' + sticker.StickerNumber
FROM
(
SELECT DISTINCT LTRIM(RTRIM(m.NNNKL)) AS StickerNumber
FROM dbo.EKZMK m
WHERE m.IDEKZ = z.IDEKZ
AND NULLIF(LTRIM(RTRIM(m.NNNKL)), N'') IS NOT NULL
) sticker
ORDER BY sticker.StickerNumber
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(max)'),
1,
1,
N'') AS StickerNumbers
) stickers
WHERE ISNULL(z.IsDeleted, 0) = 0 WHERE ISNULL(z.IsDeleted, 0) = 0
ORDER BY ownerOrg.NMFRPD, areas.NMOI, names.NMTP, tips.TP, tprz.DPZN, z.NNZV, z.IDEKZ;"; ORDER BY ownerOrg.NMFRPD, areas.NMOI, names.NMTP, tips.TP, tprz.DPZN, z.NNZV, z.IDEKZ;";
@@ -202,6 +222,7 @@ ORDER BY ownerOrg.NMFRPD, areas.NMOI, names.NMTP, tips.TP, tprz.DPZN, z.NNZV, z.
OwnerOrganizationName = ReferenceDirectorySqlHelpers.GetString(reader, "OwnerOrganizationName"), OwnerOrganizationName = ReferenceDirectorySqlHelpers.GetString(reader, "OwnerOrganizationName"),
SerialNumber = ReferenceDirectorySqlHelpers.GetString(reader, "SerialNumber"), SerialNumber = ReferenceDirectorySqlHelpers.GetString(reader, "SerialNumber"),
InventoryNumber = ReferenceDirectorySqlHelpers.GetString(reader, "InventoryNumber"), InventoryNumber = ReferenceDirectorySqlHelpers.GetString(reader, "InventoryNumber"),
StickerNumbers = ReferenceDirectorySqlHelpers.GetString(reader, "StickerNumbers"),
Notes = ReferenceDirectorySqlHelpers.GetString(reader, "Notes") Notes = ReferenceDirectorySqlHelpers.GetString(reader, "Notes")
}); });
} }
@@ -222,6 +243,8 @@ SELECT
m.NNZVPV AS DocumentNumber, m.NNZVPV AS DocumentNumber,
verificationDocument.NNDMS AS VerificationDocumentNumber, verificationDocument.NNDMS AS VerificationDocumentNumber,
verificationDocument.DTDMS AS VerificationDocumentDate, verificationDocument.DTDMS AS VerificationDocumentDate,
m.NNNKL AS StickerNumber,
verifier.PRFIO AS VerifierName,
m.PRMK AS PeriodMonths, m.PRMK AS PeriodMonths,
m.DTPRM AS AcceptedOn, m.DTPRM AS AcceptedOn,
m.DTMKPL AS PlannedOn, m.DTMKPL AS PlannedOn,
@@ -232,6 +255,7 @@ SELECT
FROM dbo.EKZMK m FROM dbo.EKZMK m
LEFT JOIN dbo.SPVDMK verificationType ON verificationType.IDSPVDMK = m.IDSPVDMK LEFT JOIN dbo.SPVDMK verificationType ON verificationType.IDSPVDMK = m.IDSPVDMK
LEFT JOIN dbo.FRPD organization ON organization.IDFRPD = m.IDFRPD LEFT JOIN dbo.FRPD organization ON organization.IDFRPD = m.IDFRPD
LEFT JOIN dbo.PRSN verifier ON verifier.IDPRSN = m.IDPRSN
OUTER APPLY OUTER APPLY
( (
SELECT TOP (1) SELECT TOP (1)
@@ -271,6 +295,8 @@ ORDER BY ISNULL(m.DTPRM, CONVERT(datetime, '19000101', 112)) DESC, m.IDEKZMK DES
DocumentNumber = ReferenceDirectorySqlHelpers.GetString(reader, "DocumentNumber"), DocumentNumber = ReferenceDirectorySqlHelpers.GetString(reader, "DocumentNumber"),
VerificationDocumentNumber = ReferenceDirectorySqlHelpers.GetString(reader, "VerificationDocumentNumber"), VerificationDocumentNumber = ReferenceDirectorySqlHelpers.GetString(reader, "VerificationDocumentNumber"),
VerificationDocumentDate = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "VerificationDocumentDate"), VerificationDocumentDate = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "VerificationDocumentDate"),
StickerNumber = ReferenceDirectorySqlHelpers.GetString(reader, "StickerNumber"),
VerifierName = ReferenceDirectorySqlHelpers.GetString(reader, "VerifierName"),
PeriodMonths = ReferenceDirectorySqlHelpers.GetInt32(reader, "PeriodMonths"), PeriodMonths = ReferenceDirectorySqlHelpers.GetInt32(reader, "PeriodMonths"),
AcceptedOn = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "AcceptedOn"), AcceptedOn = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "AcceptedOn"),
PlannedOn = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "PlannedOn"), PlannedOn = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "PlannedOn"),

View File

@@ -119,28 +119,25 @@
IsReadOnly="True" IsReadOnly="True"
HeadersVisibility="Column"> HeadersVisibility="Column">
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn Header="Документ" <DataGridTextColumn Header="ПСВ/Акт-справка"
Width="220" Width="220"
Binding="{Binding DocumentNumber}" /> Binding="{Binding DocumentNumber}" />
<DataGridTextColumn Header="Документ по поверке" <DataGridTextColumn Header="Документ по поверке"
Width="180" Width="180"
Binding="{Binding VerificationDocumentDisplay}" /> Binding="{Binding VerificationDocumentDisplay}" />
<DataGridTextColumn Header="Вид МК" <DataGridTextColumn Header="Номер наклейки"
Width="120" Width="140"
Binding="{Binding VerificationTypeName}" /> Binding="{Binding StickerNumber}" />
<DataGridTextColumn Header="Организация" <DataGridTextColumn Header="Поверитель"
Width="220" Width="180"
Binding="{Binding VerificationOrganizationName}" /> Binding="{Binding VerifierName}" />
<DataGridTextColumn Header="Период, мес." <DataGridTextColumn Header="Период, мес."
Width="95" Width="95"
Binding="{Binding PeriodMonths}" /> Binding="{Binding PeriodMonths}" />
<DataGridTextColumn Header="Принят" <DataGridTextColumn Header="Принят"
Width="95" Width="95"
Binding="{Binding AcceptedOn, StringFormat=d}" /> Binding="{Binding AcceptedOn, StringFormat=d}" />
<DataGridTextColumn Header="План" <DataGridTextColumn Header="Поверен"
Width="95"
Binding="{Binding PlannedOn, StringFormat=d}" />
<DataGridTextColumn Header="Выполнен"
Width="95" Width="95"
Binding="{Binding PerformedOn, StringFormat=d}" /> Binding="{Binding PerformedOn, StringFormat=d}" />
<DataGridTextColumn Header="Выдан" <DataGridTextColumn Header="Выдан"

View File

@@ -183,6 +183,7 @@ namespace XLAB2
OwnerOrganizationName = source.OwnerOrganizationName, OwnerOrganizationName = source.OwnerOrganizationName,
SerialNumber = source.SerialNumber, SerialNumber = source.SerialNumber,
InventoryNumber = source.InventoryNumber, InventoryNumber = source.InventoryNumber,
StickerNumbers = source.StickerNumbers,
Notes = source.Notes Notes = source.Notes
}; };
} }
@@ -422,6 +423,7 @@ namespace XLAB2
item == null ? null : item.RegistryNumber, item == null ? null : item.RegistryNumber,
item == null ? null : item.SerialNumber, item == null ? null : item.SerialNumber,
item == null ? null : item.InventoryNumber, item == null ? null : item.InventoryNumber,
item == null ? null : item.StickerNumbers,
item == null ? null : item.Notes item == null ? null : item.Notes
}.Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); })) }.Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); }))
.ToUpperInvariant(); .ToUpperInvariant();

View File

@@ -434,7 +434,7 @@
SelectedItem="{Binding SelectedDocumentLine, Mode=TwoWay}" SelectedItem="{Binding SelectedDocumentLine, Mode=TwoWay}"
AutoGenerateColumns="False" AutoGenerateColumns="False"
CanUserAddRows="False" CanUserAddRows="False"
IsReadOnly="True" IsReadOnly="{Binding IsDocumentLinesReadOnly}"
HeadersVisibility="Column"> HeadersVisibility="Column">
<DataGrid.ContextMenu> <DataGrid.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> <ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
@@ -475,21 +475,30 @@
</DataGridTemplateColumn> </DataGridTemplateColumn>
<DataGridTextColumn Header="Зав. №" <DataGridTextColumn Header="Зав. №"
Width="120" Width="120"
IsReadOnly="True"
Binding="{Binding SerialNumber}" /> Binding="{Binding SerialNumber}" />
<DataGridTextColumn Header="Комплектность"
Width="240"
Binding="{Binding Completeness, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="Дата поверки" <DataGridTextColumn Header="Дата поверки"
Width="110" Width="110"
IsReadOnly="True"
Binding="{Binding VerificationDateDisplay}" /> Binding="{Binding VerificationDateDisplay}" />
<DataGridTextColumn Header="Поверитель" <DataGridTextColumn Header="Поверитель"
Width="180" Width="180"
IsReadOnly="True"
Binding="{Binding VerifierName}" /> Binding="{Binding VerifierName}" />
<DataGridTextColumn Header="Номер наклейки" <DataGridTextColumn Header="Номер наклейки"
Width="150" Width="150"
IsReadOnly="True"
Binding="{Binding StickerNumber}" /> Binding="{Binding StickerNumber}" />
<DataGridTextColumn Header="Результат поверки" <DataGridTextColumn Header="Результат поверки"
Width="140" Width="140"
IsReadOnly="True"
Binding="{Binding ResultText}" /> Binding="{Binding ResultText}" />
<DataGridTextColumn Header="Номер документа по поверке" <DataGridTextColumn Header="Номер документа по поверке"
Width="240" Width="240"
IsReadOnly="True"
Binding="{Binding VerificationDocumentDisplay}" /> Binding="{Binding VerificationDocumentDisplay}" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

View File

@@ -206,6 +206,11 @@ namespace XLAB2
} }
} }
public bool IsDocumentLinesReadOnly
{
get { return !CanModifySelectedDocument(); }
}
public DateTime? HeaderIssuedOn public DateTime? HeaderIssuedOn
{ {
get { return _headerIssuedOn; } get { return _headerIssuedOn; }
@@ -228,6 +233,7 @@ namespace XLAB2
RaiseCommandStates(); RaiseCommandStates();
OnPropertyChanged("IsCustomerEditable"); OnPropertyChanged("IsCustomerEditable");
OnPropertyChanged("IsDocumentHeaderEditable"); OnPropertyChanged("IsDocumentHeaderEditable");
OnPropertyChanged("IsDocumentLinesReadOnly");
} }
} }
} }
@@ -293,6 +299,7 @@ namespace XLAB2
RaiseCommandStates(); RaiseCommandStates();
OnPropertyChanged("IsCustomerEditable"); OnPropertyChanged("IsCustomerEditable");
OnPropertyChanged("IsDocumentHeaderEditable"); OnPropertyChanged("IsDocumentHeaderEditable");
OnPropertyChanged("IsDocumentLinesReadOnly");
LoadSelectedDocumentAsync(); LoadSelectedDocumentAsync();
} }
} }
@@ -2537,7 +2544,8 @@ namespace XLAB2
var wasDraft = selectedDocument.IsDraft; var wasDraft = selectedDocument.IsDraft;
var closingNow = !selectedDocument.IssuedOn.HasValue && request.IssuedOn.HasValue; var closingNow = !selectedDocument.IssuedOn.HasValue && request.IssuedOn.HasValue;
var printDocument = closingNow ? CreateSavedDocumentSummaryForPrint(selectedDocument, request) : null; var printDocument = closingNow ? CreateSavedDocumentSummaryForPrint(selectedDocument, request) : null;
var result = await Task.Run(delegate { return _service.SaveDocument(currentDocumentNumber, request, pendingLines); }); var documentLinesSnapshot = DocumentLines.ToList();
var result = await Task.Run(delegate { return _service.SaveDocument(currentDocumentNumber, request, documentLinesSnapshot); });
_pendingLinesByDocumentKey.Remove(documentKey); _pendingLinesByDocumentKey.Remove(documentKey);
if (wasDraft) if (wasDraft)

View File

@@ -11,6 +11,8 @@ namespace XLAB2
{ {
internal sealed class PsvDataService internal sealed class PsvDataService
{ {
private const int EkzMkCompletenessMaxLength = 600;
public bool DocumentNumberExists(string documentNumber, string excludeDocumentNumber) public bool DocumentNumberExists(string documentNumber, string excludeDocumentNumber)
{ {
var normalizedNumber = NormalizeDocumentNumber(documentNumber); var normalizedNumber = NormalizeDocumentNumber(documentNumber);
@@ -1816,7 +1818,7 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, sizeInfo.NNGSRS;";
} }
} }
public DocumentSaveResult SaveDocument(string currentDocumentNumber, DocumentEditorResult document, IEnumerable<PsvDocumentLine> pendingLines) public DocumentSaveResult SaveDocument(string currentDocumentNumber, DocumentEditorResult document, IEnumerable<PsvDocumentLine> documentLines)
{ {
if (document == null) if (document == null)
{ {
@@ -1831,14 +1833,23 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, sizeInfo.NNGSRS;";
document.DocumentNumber = normalizedNumber; document.DocumentNumber = normalizedNumber;
var distinctPendingLines = pendingLines == null var materializedDocumentLines = documentLines == null
? new List<PsvDocumentLine>() ? new List<PsvDocumentLine>()
: pendingLines : documentLines
.Where(IsPendingLineReadyForSave) .Where(delegate(PsvDocumentLine line) { return line != null; })
.GroupBy(GetPendingLineSaveKey, StringComparer.OrdinalIgnoreCase)
.Select(delegate(IGrouping<string, PsvDocumentLine> group) { return group.First(); })
.ToList(); .ToList();
var distinctPendingLines = materializedDocumentLines
.Where(IsPendingLineReadyForSave)
.GroupBy(GetPendingLineSaveKey, StringComparer.OrdinalIgnoreCase)
.Select(delegate(IGrouping<string, PsvDocumentLine> group) { return group.First(); })
.ToList();
var persistedLines = materializedDocumentLines
.Where(delegate(PsvDocumentLine line) { return !line.IsPendingInsert && line.CardId > 0; })
.GroupBy(delegate(PsvDocumentLine line) { return line.CardId; })
.Select(delegate(IGrouping<int, PsvDocumentLine> group) { return group.First(); })
.ToList();
using (var connection = CreateConnection()) using (var connection = CreateConnection())
{ {
connection.Open(); connection.Open();
@@ -1872,6 +1883,12 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, sizeInfo.NNGSRS;";
{ {
throw new InvalidOperationException("Строки EKZMK для выбранного ПСВ не найдены."); throw new InvalidOperationException("Строки EKZMK для выбранного ПСВ не найдены.");
} }
var updatedCompletenessCount = UpdateDocumentLineCompleteness(connection, transaction, normalizedNumber, persistedLines);
if (updatedCompletenessCount > updatedEkzMkCount)
{
updatedEkzMkCount = updatedCompletenessCount;
}
} }
var insertedEkzMkCount = 0; var insertedEkzMkCount = 0;
@@ -3203,7 +3220,7 @@ VALUES
@idsptsmp, @idsptsmp,
@idspssmp, @idspssmp,
@GUIDEKZMK, @GUIDEKZMK,
NULL, @DSEKZMK,
NULL, NULL,
NULL, NULL,
NULL, NULL,
@@ -3257,6 +3274,9 @@ SELECT CAST(SCOPE_IDENTITY() AS int);";
command.Parameters.Add("@idsptsmp", SqlDbType.Int).Value = (object)template.IdSptsmp ?? DBNull.Value; command.Parameters.Add("@idsptsmp", SqlDbType.Int).Value = (object)template.IdSptsmp ?? DBNull.Value;
command.Parameters.Add("@idspssmp", SqlDbType.Int).Value = (object)template.IdSpssmp ?? DBNull.Value; command.Parameters.Add("@idspssmp", SqlDbType.Int).Value = (object)template.IdSpssmp ?? DBNull.Value;
command.Parameters.Add("@GUIDEKZMK", SqlDbType.UniqueIdentifier).Value = Guid.NewGuid(); command.Parameters.Add("@GUIDEKZMK", SqlDbType.UniqueIdentifier).Value = Guid.NewGuid();
command.Parameters.Add("@DSEKZMK", SqlDbType.NVarChar, EkzMkCompletenessMaxLength).Value = pendingLine == null
? DBNull.Value
: (object)NormalizeOptionalCompleteness(pendingLine.Notes) ?? DBNull.Value;
command.Parameters.Add("@NRVRMNDmp", SqlDbType.Decimal).Value = (object)template.Nrvrmndmp ?? DBNull.Value; command.Parameters.Add("@NRVRMNDmp", SqlDbType.Decimal).Value = (object)template.Nrvrmndmp ?? DBNull.Value;
command.Parameters["@NRVRMNDmp"].Precision = 10; command.Parameters["@NRVRMNDmp"].Precision = 10;
command.Parameters["@NRVRMNDmp"].Scale = 2; command.Parameters["@NRVRMNDmp"].Scale = 2;
@@ -4297,6 +4317,75 @@ ORDER BY blocker.TableName;";
return normalizedValue; return normalizedValue;
} }
private static int UpdateDocumentLineCompleteness(
SqlConnection connection,
SqlTransaction transaction,
string documentNumber,
IEnumerable<PsvDocumentLine> persistedLines)
{
var materializedLines = persistedLines == null
? new List<PsvDocumentLine>()
: persistedLines
.Where(delegate(PsvDocumentLine line) { return line != null && line.CardId > 0; })
.GroupBy(delegate(PsvDocumentLine line) { return line.CardId; })
.Select(delegate(IGrouping<int, PsvDocumentLine> group) { return group.First(); })
.ToList();
var updatedCount = 0;
foreach (var line in materializedLines)
{
updatedCount += UpdateDocumentLineCompletenessCore(
connection,
transaction,
documentNumber,
line.CardId,
NormalizeOptionalCompleteness(line.Notes));
}
return updatedCount;
}
private static int UpdateDocumentLineCompletenessCore(
SqlConnection connection,
SqlTransaction transaction,
string documentNumber,
int cardId,
string completeness)
{
const string sql = @"
UPDATE dbo.EKZMK
SET DSEKZMK = @Completeness
WHERE NNZVPV = @DocumentNumber
AND IDEKZMK = @CardId;
SELECT @@ROWCOUNT;";
using (var command = new SqlCommand(sql, connection, transaction))
{
command.CommandTimeout = SqlServerConnectionFactory.Current.Options.CommandTimeoutSeconds;
command.Parameters.Add("@DocumentNumber", SqlDbType.NVarChar, 60).Value = documentNumber;
command.Parameters.Add("@CardId", SqlDbType.Int).Value = cardId;
command.Parameters.Add("@Completeness", SqlDbType.NVarChar, EkzMkCompletenessMaxLength).Value = (object)completeness ?? DBNull.Value;
return Convert.ToInt32(command.ExecuteScalar());
}
}
private static string NormalizeOptionalCompleteness(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return null;
}
var normalizedValue = value.Trim();
if (normalizedValue.Length > EkzMkCompletenessMaxLength)
{
throw new InvalidOperationException(string.Format("Комплектность не должна превышать {0} символов.", EkzMkCompletenessMaxLength));
}
return normalizedValue;
}
private static int UpdateDocumentHeader(SqlConnection connection, SqlTransaction transaction, string currentDocumentNumber, DocumentEditorResult document) private static int UpdateDocumentHeader(SqlConnection connection, SqlTransaction transaction, string currentDocumentNumber, DocumentEditorResult document)
{ {
const string sql = @" const string sql = @"

View File

@@ -204,6 +204,7 @@ namespace XLAB2
public sealed class PsvDocumentLine : ObservableObject public sealed class PsvDocumentLine : ObservableObject
{ {
private bool _isBatchSelected; private bool _isBatchSelected;
private string _notes;
public int CardId { get; set; } public int CardId { get; set; }
@@ -257,7 +258,23 @@ namespace XLAB2
public string RejectionReason { get; set; } public string RejectionReason { get; set; }
public string Notes { get; set; } public string Notes
{
get { return _notes; }
set
{
if (SetProperty(ref _notes, value))
{
OnPropertyChanged("Completeness");
}
}
}
public string Completeness
{
get { return Notes; }
set { Notes = value; }
}
public bool IsPendingInsert { get; set; } public bool IsPendingInsert { get; set; }

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace XLAB2 namespace XLAB2
@@ -12,8 +13,11 @@ namespace XLAB2
private const int OpenPsvTableColumnCount = 7; private const int OpenPsvTableColumnCount = 7;
private const int ClosePsvTableColumnCount = 12; private const int ClosePsvTableColumnCount = 12;
private const int PrintDialogId = 88; private const int PrintDialogId = 88;
private const int WordActiveEndAdjustedPageNumber = 1;
private const int WordAlertsNone = 0; private const int WordAlertsNone = 0;
private const int WordParagraphTrue = -1;
private const int WordCloseDoNotSaveChanges = 0; private const int WordCloseDoNotSaveChanges = 0;
private const int WordStatisticPages = 2;
public void PrintDocument(PsvDocumentSummary document, IReadOnlyList<PsvDocumentLine> lines) public void PrintDocument(PsvDocumentSummary document, IReadOnlyList<PsvDocumentLine> lines)
{ {
@@ -232,6 +236,9 @@ namespace XLAB2
ReleaseComObject(row); ReleaseComObject(row);
} }
} }
// If trailing document text spills onto a new page, move the last table row with it.
EnsureTableSpillsToNextPage(document, table);
} }
finally finally
{ {
@@ -239,6 +246,60 @@ namespace XLAB2
} }
} }
private static void EnsureTableSpillsToNextPage(dynamic document, dynamic table)
{
if (document == null || table == null)
{
return;
}
var rowCount = Convert.ToInt32(table.Rows.Count, CultureInfo.InvariantCulture);
if (rowCount <= 1)
{
return;
}
RepaginateDocument(document);
var totalPages = InvokeComIntMethod(document, "ComputeStatistics", WordStatisticPages);
if (totalPages <= 1)
{
return;
}
dynamic lastRow = null;
dynamic firstCell = null;
dynamic lastRowRange = null;
dynamic firstCellRange = null;
dynamic paragraphFormat = null;
try
{
lastRow = table.Rows.Item(rowCount);
lastRowRange = lastRow.Range;
var lastRowPage = GetRangePageNumber(lastRowRange);
if (lastRowPage >= totalPages)
{
return;
}
firstCell = lastRow.Cells.Item(1);
firstCellRange = firstCell.Range;
paragraphFormat = firstCellRange.ParagraphFormat;
paragraphFormat.PageBreakBefore = WordParagraphTrue;
RepaginateDocument(document);
}
finally
{
ReleaseComObject(paragraphFormat);
ReleaseComObject(firstCellRange);
ReleaseComObject(lastRowRange);
ReleaseComObject(firstCell);
ReleaseComObject(lastRow);
}
}
private static void EnsurePsvTableLayout(dynamic table, int expectedColumnCount) private static void EnsurePsvTableLayout(dynamic table, int expectedColumnCount)
{ {
if (table == null) if (table == null)
@@ -268,6 +329,16 @@ namespace XLAB2
} }
} }
private static int GetRangePageNumber(object range)
{
return InvokeComIndexedIntProperty(range, "Information", WordActiveEndAdjustedPageNumber);
}
private static void RepaginateDocument(object document)
{
InvokeComMethod(document, "Repaginate");
}
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;
@@ -317,6 +388,55 @@ namespace XLAB2
} }
} }
private static int InvokeComIndexedIntProperty(object target, string propertyName, object argument)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
return Convert.ToInt32(
target.GetType().InvokeMember(
propertyName,
BindingFlags.GetProperty,
null,
target,
new[] { argument }),
CultureInfo.InvariantCulture);
}
private static int InvokeComIntMethod(object target, string methodName, object argument)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
return Convert.ToInt32(
target.GetType().InvokeMember(
methodName,
BindingFlags.InvokeMethod,
null,
target,
new[] { argument }),
CultureInfo.InvariantCulture);
}
private static void InvokeComMethod(object target, string methodName)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
target.GetType().InvokeMember(
methodName,
BindingFlags.InvokeMethod,
null,
target,
Array.Empty<object>());
}
private static IReadOnlyList<PrintedGroupRow> BuildPrintedGroups(IEnumerable<PsvDocumentLine> lines, bool includeClosedDetails) private static IReadOnlyList<PrintedGroupRow> BuildPrintedGroups(IEnumerable<PsvDocumentLine> lines, bool includeClosedDetails)
{ {
return (lines ?? Enumerable.Empty<PsvDocumentLine>()) return (lines ?? Enumerable.Empty<PsvDocumentLine>())
@@ -378,7 +498,7 @@ namespace XLAB2
return string.Empty; return string.Empty;
} }
if (serialNumbers.Count > 3) if (serialNumbers.Count > 10)
{ {
return string.Format(CultureInfo.InvariantCulture, "{0} зав. номеров", serialNumbers.Count); return string.Format(CultureInfo.InvariantCulture, "{0} зав. номеров", serialNumbers.Count);
} }

Binary file not shown.

Binary file not shown.

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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