edit
This commit is contained in:
832
XLAB2/EkzDirectoryService.cs
Normal file
832
XLAB2/EkzDirectoryService.cs
Normal file
@@ -0,0 +1,832 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace XLAB2
|
||||
{
|
||||
internal sealed class EkzDirectoryService
|
||||
{
|
||||
private static readonly string[] CascadingEkzChildTables = { "EKZMK", "EKZMCP" };
|
||||
|
||||
private static readonly string[] CascadingEkzMkChildTables = { "EKZMKFCTVL", "EKZMKDH", "EKZMKEKZK", "EKZMKND", "KSPELEKZMK" };
|
||||
|
||||
public int AddEkzItem(EkzDirectoryItem item)
|
||||
{
|
||||
var normalizedItem = NormalizeEkzItem(item);
|
||||
|
||||
const string sql = @"
|
||||
INSERT INTO dbo.EKZ
|
||||
(
|
||||
IDTPRZ,
|
||||
IDFRPDV,
|
||||
KLSIPR,
|
||||
NNZV,
|
||||
NNIN,
|
||||
DSEKZ,
|
||||
GUIDEKZ,
|
||||
IsDeleted
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@TypeSizeId,
|
||||
@OwnerOrganizationId,
|
||||
1,
|
||||
@SerialNumber,
|
||||
@InventoryNumber,
|
||||
@Notes,
|
||||
@Guid,
|
||||
0
|
||||
);
|
||||
|
||||
SELECT CAST(SCOPE_IDENTITY() AS int);";
|
||||
|
||||
using (var connection = ReferenceDirectorySqlHelpers.CreateConnection())
|
||||
using (var command = new SqlCommand(sql, connection))
|
||||
{
|
||||
connection.Open();
|
||||
EnsureEkzIsUnique(connection, normalizedItem.TypeSizeId, normalizedItem.OwnerOrganizationId, normalizedItem.SerialNumber, null);
|
||||
|
||||
command.CommandTimeout = ReferenceDirectorySqlHelpers.GetCommandTimeoutSeconds();
|
||||
command.Parameters.Add("@TypeSizeId", SqlDbType.Int).Value = normalizedItem.TypeSizeId;
|
||||
command.Parameters.Add("@OwnerOrganizationId", SqlDbType.Int).Value = normalizedItem.OwnerOrganizationId;
|
||||
command.Parameters.Add("@SerialNumber", SqlDbType.VarChar, EkzDirectoryRules.SerialNumberMaxLength).Value = normalizedItem.SerialNumber;
|
||||
ReferenceDirectorySqlHelpers.AddNullableStringParameter(command, "@InventoryNumber", SqlDbType.VarChar, EkzDirectoryRules.InventoryNumberMaxLength, normalizedItem.InventoryNumber);
|
||||
ReferenceDirectorySqlHelpers.AddNullableStringParameter(command, "@Notes", SqlDbType.VarChar, EkzDirectoryRules.NotesMaxLength, normalizedItem.Notes);
|
||||
command.Parameters.Add("@Guid", SqlDbType.UniqueIdentifier).Value = Guid.NewGuid();
|
||||
|
||||
return Convert.ToInt32(command.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
|
||||
public EkzDeletePreview GetEkzDeletePreview(int id)
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return new EkzDeletePreview
|
||||
{
|
||||
CanDelete = false,
|
||||
ImpactItems = Array.Empty<EkzDeleteImpactItem>(),
|
||||
WarningMessage = "Не выбрана запись EKZ для удаления."
|
||||
};
|
||||
}
|
||||
|
||||
using (var connection = ReferenceDirectorySqlHelpers.CreateConnection())
|
||||
{
|
||||
connection.Open();
|
||||
return BuildEkzDeletePreview(connection, null, id);
|
||||
}
|
||||
}
|
||||
|
||||
public EkzDeleteResult DeleteEkzItem(int id)
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
throw new InvalidOperationException("Не выбрана запись EKZ для удаления.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (var connection = ReferenceDirectorySqlHelpers.CreateConnection())
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
using (var transaction = connection.BeginTransaction())
|
||||
{
|
||||
var preview = BuildEkzDeletePreview(connection, transaction, id);
|
||||
if (!preview.CanDelete)
|
||||
{
|
||||
transaction.Rollback();
|
||||
return new EkzDeleteResult
|
||||
{
|
||||
IsDeleted = false,
|
||||
ImpactItems = preview.ImpactItems ?? Array.Empty<EkzDeleteImpactItem>(),
|
||||
WarningMessage = preview.WarningMessage
|
||||
};
|
||||
}
|
||||
|
||||
var impactItems = new List<EkzDeleteImpactItem>();
|
||||
AddImpactItem(impactItems, "EKZMKFCTVL", DeleteEkzMkFctvl(connection, transaction, id));
|
||||
AddImpactItem(impactItems, "EKZMKDH", DeleteEkzMkDh(connection, transaction, id));
|
||||
AddImpactItem(impactItems, "EKZMKEKZK", DeleteEkzMkEkzk(connection, transaction, id));
|
||||
AddImpactItem(impactItems, "EKZMKND", DeleteEkzMkNd(connection, transaction, id));
|
||||
AddImpactItem(impactItems, "KSPELEKZMK", DeleteKspelEkzMk(connection, transaction, id));
|
||||
AddImpactItem(impactItems, "DMS", DeleteEkzDms(connection, transaction, id));
|
||||
AddImpactItem(impactItems, "EKZMK", DeleteEkzMk(connection, transaction, id));
|
||||
AddImpactItem(impactItems, "EKZMCP", DeleteEkzMcp(connection, transaction, id));
|
||||
|
||||
var deletedEkzCount = DeleteEkz(connection, transaction, id);
|
||||
if (deletedEkzCount == 0)
|
||||
{
|
||||
transaction.Rollback();
|
||||
return new EkzDeleteResult
|
||||
{
|
||||
IsDeleted = false,
|
||||
ImpactItems = Array.Empty<EkzDeleteImpactItem>(),
|
||||
WarningMessage = "Запись EKZ для удаления не найдена."
|
||||
};
|
||||
}
|
||||
|
||||
AddImpactItem(impactItems, "EKZ", deletedEkzCount);
|
||||
transaction.Commit();
|
||||
|
||||
return new EkzDeleteResult
|
||||
{
|
||||
IsDeleted = true,
|
||||
ImpactItems = OrderImpactItems(impactItems)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SqlException ex) when (ex.Number == 547)
|
||||
{
|
||||
return new EkzDeleteResult
|
||||
{
|
||||
IsDeleted = false,
|
||||
ImpactItems = Array.Empty<EkzDeleteImpactItem>(),
|
||||
WarningMessage = CreateEkzDeleteFailedMessage(ex)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<EkzDirectoryItem> LoadEkzItems()
|
||||
{
|
||||
const string sql = @"
|
||||
SELECT
|
||||
z.IDEKZ AS Id,
|
||||
z.IDTPRZ AS TypeSizeId,
|
||||
areas.NMOI AS MeasurementAreaName,
|
||||
names.NMTP AS InstrumentName,
|
||||
tips.TP AS TypeName,
|
||||
tprz.DPZN AS RangeText,
|
||||
tprz.HRTC AS AccuracyText,
|
||||
tprz.NNGSRS AS RegistryNumber,
|
||||
z.IDFRPDV AS OwnerOrganizationId,
|
||||
ownerOrg.NMFRPD AS OwnerOrganizationName,
|
||||
z.NNZV AS SerialNumber,
|
||||
z.NNIN AS InventoryNumber,
|
||||
CAST(z.DSEKZ AS nvarchar(max)) AS Notes
|
||||
FROM dbo.EKZ z
|
||||
JOIN dbo.TPRZ tprz ON tprz.IDTPRZ = z.IDTPRZ
|
||||
JOIN dbo.TIPS tips ON tips.IDTIPS = tprz.IDTIPS
|
||||
JOIN dbo.SPNMTP names ON names.IDSPNMTP = tips.IDSPNMTP
|
||||
JOIN dbo.SPOI areas ON areas.IDSPOI = tips.IDSPOI
|
||||
JOIN dbo.FRPD ownerOrg ON ownerOrg.IDFRPD = z.IDFRPDV
|
||||
WHERE ISNULL(z.IsDeleted, 0) = 0
|
||||
ORDER BY ownerOrg.NMFRPD, areas.NMOI, names.NMTP, tips.TP, tprz.DPZN, z.NNZV, z.IDEKZ;";
|
||||
|
||||
var items = new List<EkzDirectoryItem>();
|
||||
|
||||
using (var connection = ReferenceDirectorySqlHelpers.CreateConnection())
|
||||
using (var command = new SqlCommand(sql, connection))
|
||||
{
|
||||
connection.Open();
|
||||
command.CommandTimeout = ReferenceDirectorySqlHelpers.GetCommandTimeoutSeconds();
|
||||
|
||||
using (var reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
items.Add(new EkzDirectoryItem
|
||||
{
|
||||
Id = ReferenceDirectorySqlHelpers.GetInt32(reader, "Id"),
|
||||
TypeSizeId = ReferenceDirectorySqlHelpers.GetInt32(reader, "TypeSizeId"),
|
||||
MeasurementAreaName = ReferenceDirectorySqlHelpers.GetString(reader, "MeasurementAreaName"),
|
||||
InstrumentName = ReferenceDirectorySqlHelpers.GetString(reader, "InstrumentName"),
|
||||
TypeName = ReferenceDirectorySqlHelpers.GetString(reader, "TypeName"),
|
||||
RangeText = ReferenceDirectorySqlHelpers.GetString(reader, "RangeText"),
|
||||
AccuracyText = ReferenceDirectorySqlHelpers.GetString(reader, "AccuracyText"),
|
||||
RegistryNumber = ReferenceDirectorySqlHelpers.GetString(reader, "RegistryNumber"),
|
||||
OwnerOrganizationId = ReferenceDirectorySqlHelpers.GetInt32(reader, "OwnerOrganizationId"),
|
||||
OwnerOrganizationName = ReferenceDirectorySqlHelpers.GetString(reader, "OwnerOrganizationName"),
|
||||
SerialNumber = ReferenceDirectorySqlHelpers.GetString(reader, "SerialNumber"),
|
||||
InventoryNumber = ReferenceDirectorySqlHelpers.GetString(reader, "InventoryNumber"),
|
||||
Notes = ReferenceDirectorySqlHelpers.GetString(reader, "Notes")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public IReadOnlyList<EkzMkDirectoryItem> LoadEkzMkItems(int instrumentId)
|
||||
{
|
||||
const string sql = @"
|
||||
SELECT
|
||||
m.IDEKZMK AS CardId,
|
||||
m.IDEKZ AS InstrumentId,
|
||||
verificationType.NMVDMK AS VerificationTypeName,
|
||||
organization.NMFRPD AS VerificationOrganizationName,
|
||||
m.NNZVPV AS DocumentNumber,
|
||||
verificationDocument.NNDMS AS VerificationDocumentNumber,
|
||||
verificationDocument.DTDMS AS VerificationDocumentDate,
|
||||
m.PRMK AS PeriodMonths,
|
||||
m.DTPRM AS AcceptedOn,
|
||||
m.DTMKPL AS PlannedOn,
|
||||
m.DTMKFK AS PerformedOn,
|
||||
m.DTVDM AS IssuedOn,
|
||||
m.GDN AS IsPassed,
|
||||
CAST(m.DSEKZMK AS nvarchar(max)) AS Notes
|
||||
FROM dbo.EKZMK m
|
||||
LEFT JOIN dbo.SPVDMK verificationType ON verificationType.IDSPVDMK = m.IDSPVDMK
|
||||
LEFT JOIN dbo.FRPD organization ON organization.IDFRPD = m.IDFRPD
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
d.NND AS NNDMS,
|
||||
d.DTD AS DTDMS
|
||||
FROM dbo.DMS d
|
||||
JOIN dbo.VDODVDD vdd ON vdd.IDVDODVDD = d.IDVDODVDD
|
||||
JOIN dbo.FRDMS frdms ON frdms.IDFRDMS = d.IDFRDMS
|
||||
JOIN dbo.SPVDD spvdd ON spvdd.IDSPVDD = frdms.IDSPVDD
|
||||
WHERE d.IDOD = m.IDEKZMK
|
||||
AND vdd.IDSPVDOD = 2
|
||||
AND spvdd.IDSPVDD IN (2, 6, 8)
|
||||
ORDER BY d.DTD DESC
|
||||
) verificationDocument
|
||||
WHERE m.IDEKZ = @InstrumentId
|
||||
ORDER BY ISNULL(m.DTPRM, CONVERT(datetime, '19000101', 112)) DESC, m.IDEKZMK DESC;";
|
||||
|
||||
var items = new List<EkzMkDirectoryItem>();
|
||||
|
||||
using (var connection = ReferenceDirectorySqlHelpers.CreateConnection())
|
||||
using (var command = new SqlCommand(sql, connection))
|
||||
{
|
||||
connection.Open();
|
||||
command.CommandTimeout = ReferenceDirectorySqlHelpers.GetCommandTimeoutSeconds();
|
||||
command.Parameters.Add("@InstrumentId", SqlDbType.Int).Value = instrumentId;
|
||||
|
||||
using (var reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
items.Add(new EkzMkDirectoryItem
|
||||
{
|
||||
CardId = ReferenceDirectorySqlHelpers.GetInt32(reader, "CardId"),
|
||||
InstrumentId = ReferenceDirectorySqlHelpers.GetInt32(reader, "InstrumentId"),
|
||||
VerificationTypeName = ReferenceDirectorySqlHelpers.GetString(reader, "VerificationTypeName"),
|
||||
VerificationOrganizationName = ReferenceDirectorySqlHelpers.GetString(reader, "VerificationOrganizationName"),
|
||||
DocumentNumber = ReferenceDirectorySqlHelpers.GetString(reader, "DocumentNumber"),
|
||||
VerificationDocumentNumber = ReferenceDirectorySqlHelpers.GetString(reader, "VerificationDocumentNumber"),
|
||||
VerificationDocumentDate = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "VerificationDocumentDate"),
|
||||
PeriodMonths = ReferenceDirectorySqlHelpers.GetInt32(reader, "PeriodMonths"),
|
||||
AcceptedOn = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "AcceptedOn"),
|
||||
PlannedOn = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "PlannedOn"),
|
||||
PerformedOn = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "PerformedOn"),
|
||||
IssuedOn = ReferenceDirectorySqlHelpers.GetNullableDateTime(reader, "IssuedOn"),
|
||||
IsPassed = ReferenceDirectorySqlHelpers.GetNullableBoolean(reader, "IsPassed"),
|
||||
Notes = ReferenceDirectorySqlHelpers.GetString(reader, "Notes")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public IReadOnlyList<DirectoryLookupItem> LoadFrpdReferences()
|
||||
{
|
||||
return ReferenceDirectorySqlHelpers.LoadLookupItems(@"
|
||||
SELECT
|
||||
fr.IDFRPD AS Id,
|
||||
fr.NMFRPD AS Name
|
||||
FROM dbo.FRPD fr
|
||||
WHERE NULLIF(LTRIM(RTRIM(fr.NMFRPD)), '') IS NOT NULL
|
||||
ORDER BY fr.NMFRPD, fr.IDFRPD;");
|
||||
}
|
||||
|
||||
public IReadOnlyList<DirectoryLookupItem> LoadTypeSizeReferences()
|
||||
{
|
||||
return ReferenceDirectorySqlHelpers.LoadLookupItems(@"
|
||||
SELECT
|
||||
tprz.IDTPRZ AS Id,
|
||||
LTRIM(RTRIM(
|
||||
COALESCE(NULLIF(areas.NMOI, N'') + N' / ', N'')
|
||||
+ COALESCE(NULLIF(names.NMTP, N'') + N' / ', N'')
|
||||
+ COALESCE(NULLIF(tips.TP, N''), N'')
|
||||
+ CASE WHEN NULLIF(LTRIM(RTRIM(tprz.DPZN)), N'') IS NULL THEN N'' ELSE N' / ' + tprz.DPZN END
|
||||
+ CASE
|
||||
WHEN NULLIF(LTRIM(RTRIM(CONVERT(nvarchar(50), tprz.NNGSRS))), N'') IS NULL THEN N''
|
||||
ELSE N' / № ГР ' + CONVERT(nvarchar(50), tprz.NNGSRS)
|
||||
END
|
||||
)) AS Name
|
||||
FROM dbo.TPRZ tprz
|
||||
JOIN dbo.TIPS tips ON tips.IDTIPS = tprz.IDTIPS
|
||||
JOIN dbo.SPNMTP names ON names.IDSPNMTP = tips.IDSPNMTP
|
||||
JOIN dbo.SPOI areas ON areas.IDSPOI = tips.IDSPOI
|
||||
ORDER BY areas.NMOI, names.NMTP, tips.TP, tprz.DPZN, tprz.IDTPRZ;");
|
||||
}
|
||||
|
||||
public void UpdateEkzItem(EkzDirectoryItem item)
|
||||
{
|
||||
var normalizedItem = NormalizeEkzItem(item);
|
||||
if (normalizedItem.Id <= 0)
|
||||
{
|
||||
throw new InvalidOperationException("Не выбрана запись EKZ для изменения.");
|
||||
}
|
||||
|
||||
const string sql = @"
|
||||
UPDATE dbo.EKZ
|
||||
SET IDTPRZ = @TypeSizeId,
|
||||
IDFRPDV = @OwnerOrganizationId,
|
||||
NNZV = @SerialNumber,
|
||||
NNIN = @InventoryNumber,
|
||||
DSEKZ = @Notes
|
||||
WHERE IDEKZ = @Id;
|
||||
|
||||
SELECT @@ROWCOUNT;";
|
||||
|
||||
using (var connection = ReferenceDirectorySqlHelpers.CreateConnection())
|
||||
using (var command = new SqlCommand(sql, connection))
|
||||
{
|
||||
connection.Open();
|
||||
EnsureEkzIsUnique(connection, normalizedItem.TypeSizeId, normalizedItem.OwnerOrganizationId, normalizedItem.SerialNumber, normalizedItem.Id);
|
||||
|
||||
command.CommandTimeout = ReferenceDirectorySqlHelpers.GetCommandTimeoutSeconds();
|
||||
command.Parameters.Add("@Id", SqlDbType.Int).Value = normalizedItem.Id;
|
||||
command.Parameters.Add("@TypeSizeId", SqlDbType.Int).Value = normalizedItem.TypeSizeId;
|
||||
command.Parameters.Add("@OwnerOrganizationId", SqlDbType.Int).Value = normalizedItem.OwnerOrganizationId;
|
||||
command.Parameters.Add("@SerialNumber", SqlDbType.VarChar, EkzDirectoryRules.SerialNumberMaxLength).Value = normalizedItem.SerialNumber;
|
||||
ReferenceDirectorySqlHelpers.AddNullableStringParameter(command, "@InventoryNumber", SqlDbType.VarChar, EkzDirectoryRules.InventoryNumberMaxLength, normalizedItem.InventoryNumber);
|
||||
ReferenceDirectorySqlHelpers.AddNullableStringParameter(command, "@Notes", SqlDbType.VarChar, EkzDirectoryRules.NotesMaxLength, normalizedItem.Notes);
|
||||
|
||||
if (Convert.ToInt32(command.ExecuteScalar()) == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Запись EKZ для изменения не найдена.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static EkzDeletePreview BuildEkzDeletePreview(SqlConnection connection, SqlTransaction transaction, int id)
|
||||
{
|
||||
if (!EkzExists(connection, transaction, id))
|
||||
{
|
||||
return new EkzDeletePreview
|
||||
{
|
||||
CanDelete = false,
|
||||
ImpactItems = Array.Empty<EkzDeleteImpactItem>(),
|
||||
WarningMessage = "Запись EKZ для удаления не найдена."
|
||||
};
|
||||
}
|
||||
|
||||
var cardIds = LoadEkzMkCardIds(connection, transaction, id);
|
||||
var blockers = new List<DeleteBlockerInfo>();
|
||||
blockers.AddRange(ReferenceDirectorySqlHelpers.LoadDeleteBlockersFromForeignKeys(connection, transaction, "EKZ", id, CascadingEkzChildTables));
|
||||
blockers.AddRange(LoadUnhandledDeleteBlockers(connection, transaction, "EKZMK", cardIds, CascadingEkzMkChildTables));
|
||||
|
||||
var impactItems = BuildImpactItems(connection, transaction, id, cardIds);
|
||||
var mergedBlockers = MergeBlockers(blockers);
|
||||
if (mergedBlockers.Count > 0)
|
||||
{
|
||||
return new EkzDeletePreview
|
||||
{
|
||||
CanDelete = false,
|
||||
ImpactItems = impactItems,
|
||||
WarningMessage = CreateEkzCascadeBlockedMessage(mergedBlockers)
|
||||
};
|
||||
}
|
||||
|
||||
return new EkzDeletePreview
|
||||
{
|
||||
CanDelete = true,
|
||||
ImpactItems = impactItems,
|
||||
ConfirmationMessage = CreateEkzDeleteConfirmationMessage(impactItems)
|
||||
};
|
||||
}
|
||||
|
||||
private static IReadOnlyList<EkzDeleteImpactItem> BuildImpactItems(SqlConnection connection, SqlTransaction transaction, int instrumentId, IReadOnlyCollection<int> cardIds)
|
||||
{
|
||||
var impactItems = new List<EkzDeleteImpactItem>();
|
||||
AddImpactItem(impactItems, "EKZ", 1);
|
||||
AddImpactItem(impactItems, "EKZMK", cardIds == null ? 0 : cardIds.Count);
|
||||
AddImpactItem(impactItems, "DMS", CountEkzDms(connection, transaction, instrumentId));
|
||||
AddImpactItem(impactItems, "EKZMKFCTVL", CountEkzMkFctvl(connection, transaction, instrumentId));
|
||||
AddImpactItem(impactItems, "EKZMKDH", CountEkzMkDh(connection, transaction, instrumentId));
|
||||
AddImpactItem(impactItems, "EKZMKEKZK", CountEkzMkEkzk(connection, transaction, instrumentId));
|
||||
AddImpactItem(impactItems, "EKZMKND", CountEkzMkNd(connection, transaction, instrumentId));
|
||||
AddImpactItem(impactItems, "KSPELEKZMK", CountKspelEkzMk(connection, transaction, instrumentId));
|
||||
AddImpactItem(impactItems, "EKZMCP", CountEkzMcp(connection, transaction, instrumentId));
|
||||
return OrderImpactItems(impactItems);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<EkzDeleteImpactItem> OrderImpactItems(IEnumerable<EkzDeleteImpactItem> impactItems)
|
||||
{
|
||||
var order = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "EKZ", 1 },
|
||||
{ "EKZMK", 2 },
|
||||
{ "DMS", 3 },
|
||||
{ "EKZMKFCTVL", 4 },
|
||||
{ "EKZMKDH", 5 },
|
||||
{ "EKZMKEKZK", 6 },
|
||||
{ "EKZMKND", 7 },
|
||||
{ "KSPELEKZMK", 8 },
|
||||
{ "EKZMCP", 9 }
|
||||
};
|
||||
|
||||
return (impactItems ?? Enumerable.Empty<EkzDeleteImpactItem>())
|
||||
.Where(delegate(EkzDeleteImpactItem item) { return item != null && item.RowCount > 0; })
|
||||
.OrderBy(delegate(EkzDeleteImpactItem item)
|
||||
{
|
||||
int value;
|
||||
return order.TryGetValue(item.TableName ?? string.Empty, out value) ? value : int.MaxValue;
|
||||
})
|
||||
.ThenBy(delegate(EkzDeleteImpactItem item) { return item.TableName; }, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static void AddImpactItem(ICollection<EkzDeleteImpactItem> impactItems, string tableName, int rowCount)
|
||||
{
|
||||
if (impactItems == null || string.IsNullOrWhiteSpace(tableName) || rowCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
impactItems.Add(new EkzDeleteImpactItem
|
||||
{
|
||||
TableName = tableName,
|
||||
RowCount = rowCount
|
||||
});
|
||||
}
|
||||
|
||||
private static string CreateEkzDeleteConfirmationMessage(IEnumerable<EkzDeleteImpactItem> impactItems)
|
||||
{
|
||||
var items = OrderImpactItems(impactItems).ToList();
|
||||
var lines = new List<string>();
|
||||
if (items.Count == 0)
|
||||
{
|
||||
lines.Add("Будет физически удалена только запись EKZ.");
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.Add("Будут физически удалены записи:");
|
||||
foreach (var item in items)
|
||||
{
|
||||
lines.Add(string.Format("{0}: {1}", item.TableName, item.RowCount));
|
||||
}
|
||||
}
|
||||
|
||||
lines.Add(string.Empty);
|
||||
lines.Add("Продолжить?");
|
||||
return string.Join(Environment.NewLine, lines.ToArray());
|
||||
}
|
||||
|
||||
private static string CreateEkzCascadeBlockedMessage(IEnumerable<DeleteBlockerInfo> blockers)
|
||||
{
|
||||
return string.Format(
|
||||
"Экземпляр не может быть удалён автоматически. Есть связанные записи в таблицах, которые не входят в каскад удаления: {0}.",
|
||||
FormatBlockerDetails(blockers));
|
||||
}
|
||||
|
||||
private static string CreateEkzDeleteFailedMessage(SqlException ex)
|
||||
{
|
||||
var suffix = ex == null || string.IsNullOrWhiteSpace(ex.Message)
|
||||
? string.Empty
|
||||
: " " + ex.Message.Trim();
|
||||
|
||||
return "Экземпляр не может быть удалён из-за ограничений ссылочной целостности БД." + suffix;
|
||||
}
|
||||
|
||||
private static string FormatBlockerDetails(IEnumerable<DeleteBlockerInfo> blockers)
|
||||
{
|
||||
var details = string.Join(", ", (blockers ?? Enumerable.Empty<DeleteBlockerInfo>())
|
||||
.Where(delegate(DeleteBlockerInfo blocker) { return blocker != null && blocker.RowCount > 0; })
|
||||
.OrderBy(delegate(DeleteBlockerInfo blocker) { return blocker.TableName; }, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(delegate(DeleteBlockerInfo blocker) { return string.Format("{0}: {1}", blocker.TableName, blocker.RowCount); }));
|
||||
|
||||
return string.IsNullOrWhiteSpace(details) ? "связанные данные" : details;
|
||||
}
|
||||
|
||||
private static List<DeleteBlockerInfo> MergeBlockers(IEnumerable<DeleteBlockerInfo> blockers)
|
||||
{
|
||||
return (blockers ?? Enumerable.Empty<DeleteBlockerInfo>())
|
||||
.Where(delegate(DeleteBlockerInfo blocker) { return blocker != null && blocker.RowCount > 0 && !string.IsNullOrWhiteSpace(blocker.TableName); })
|
||||
.GroupBy(delegate(DeleteBlockerInfo blocker) { return blocker.TableName; }, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(delegate(IGrouping<string, DeleteBlockerInfo> group)
|
||||
{
|
||||
return new DeleteBlockerInfo
|
||||
{
|
||||
TableName = group.Key,
|
||||
RowCount = group.Sum(delegate(DeleteBlockerInfo blocker) { return blocker.RowCount; })
|
||||
};
|
||||
})
|
||||
.OrderBy(delegate(DeleteBlockerInfo blocker) { return blocker.TableName; }, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static List<DeleteBlockerInfo> LoadUnhandledDeleteBlockers(SqlConnection connection, SqlTransaction transaction, string parentTableName, IEnumerable<int> ids, IEnumerable<string> excludedChildTables)
|
||||
{
|
||||
var blockers = new List<DeleteBlockerInfo>();
|
||||
foreach (var id in (ids ?? Enumerable.Empty<int>()).Where(delegate(int value) { return value > 0; }).Distinct())
|
||||
{
|
||||
blockers.AddRange(ReferenceDirectorySqlHelpers.LoadDeleteBlockersFromForeignKeys(connection, transaction, parentTableName, id, excludedChildTables));
|
||||
}
|
||||
|
||||
return MergeBlockers(blockers);
|
||||
}
|
||||
|
||||
private static bool EkzExists(SqlConnection connection, SqlTransaction transaction, int id)
|
||||
{
|
||||
const string sql = @"
|
||||
SELECT COUNT(1)
|
||||
FROM dbo.EKZ
|
||||
WHERE IDEKZ = @Id;";
|
||||
|
||||
return ExecuteScalarForId(connection, transaction, sql, id) > 0;
|
||||
}
|
||||
|
||||
private static List<int> LoadEkzMkCardIds(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
const string sql = @"
|
||||
SELECT IDEKZMK
|
||||
FROM dbo.EKZMK
|
||||
WHERE IDEKZ = @InstrumentId
|
||||
ORDER BY IDEKZMK;";
|
||||
|
||||
return ExecuteIdList(connection, transaction, sql, "@InstrumentId", instrumentId);
|
||||
}
|
||||
|
||||
private static int CountEkzMcp(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
SELECT COUNT(*)
|
||||
FROM dbo.EKZMCP
|
||||
WHERE IDEKZ = @InstrumentId;", instrumentId);
|
||||
}
|
||||
|
||||
private static int CountEkzMkFctvl(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
SELECT COUNT(*)
|
||||
FROM dbo.EKZMKFCTVL child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;", instrumentId);
|
||||
}
|
||||
|
||||
private static int CountEkzMkDh(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
SELECT COUNT(*)
|
||||
FROM dbo.EKZMKDH child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;", instrumentId);
|
||||
}
|
||||
|
||||
private static int CountEkzMkEkzk(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
SELECT COUNT(*)
|
||||
FROM dbo.EKZMKEKZK child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;", instrumentId);
|
||||
}
|
||||
|
||||
private static int CountEkzMkNd(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
SELECT COUNT(*)
|
||||
FROM dbo.EKZMKND child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;", instrumentId);
|
||||
}
|
||||
|
||||
private static int CountKspelEkzMk(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
SELECT COUNT(*)
|
||||
FROM dbo.KSPELEKZMK child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;", instrumentId);
|
||||
}
|
||||
|
||||
private static int CountEkzDms(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
SELECT COUNT(*)
|
||||
FROM dbo.DMS d
|
||||
JOIN dbo.VDODVDD vdd ON vdd.IDVDODVDD = d.IDVDODVDD
|
||||
JOIN dbo.EKZMK m ON m.IDEKZMK = d.IDOD
|
||||
WHERE m.IDEKZ = @InstrumentId
|
||||
AND vdd.IDSPVDOD = 2;", instrumentId);
|
||||
}
|
||||
|
||||
private static int DeleteEkzMcp(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
DELETE FROM dbo.EKZMCP
|
||||
WHERE IDEKZ = @InstrumentId;
|
||||
|
||||
SELECT @@ROWCOUNT;", instrumentId);
|
||||
}
|
||||
|
||||
private static int DeleteEkzMkFctvl(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
DELETE child
|
||||
FROM dbo.EKZMKFCTVL child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;
|
||||
|
||||
SELECT @@ROWCOUNT;", instrumentId);
|
||||
}
|
||||
|
||||
private static int DeleteEkzMkDh(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
DELETE child
|
||||
FROM dbo.EKZMKDH child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;
|
||||
|
||||
SELECT @@ROWCOUNT;", instrumentId);
|
||||
}
|
||||
|
||||
private static int DeleteEkzMkEkzk(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
DELETE child
|
||||
FROM dbo.EKZMKEKZK child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;
|
||||
|
||||
SELECT @@ROWCOUNT;", instrumentId);
|
||||
}
|
||||
|
||||
private static int DeleteEkzMkNd(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
DELETE child
|
||||
FROM dbo.EKZMKND child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;
|
||||
|
||||
SELECT @@ROWCOUNT;", instrumentId);
|
||||
}
|
||||
|
||||
private static int DeleteKspelEkzMk(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
DELETE child
|
||||
FROM dbo.KSPELEKZMK child
|
||||
JOIN dbo.EKZMK parent ON parent.IDEKZMK = child.IDEKZMK
|
||||
WHERE parent.IDEKZ = @InstrumentId;
|
||||
|
||||
SELECT @@ROWCOUNT;", instrumentId);
|
||||
}
|
||||
|
||||
private static int DeleteEkzDms(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
DELETE d
|
||||
FROM dbo.DMS d
|
||||
JOIN dbo.VDODVDD vdd ON vdd.IDVDODVDD = d.IDVDODVDD
|
||||
JOIN dbo.EKZMK m ON m.IDEKZMK = d.IDOD
|
||||
WHERE m.IDEKZ = @InstrumentId
|
||||
AND vdd.IDSPVDOD = 2;
|
||||
|
||||
SELECT @@ROWCOUNT;", instrumentId);
|
||||
}
|
||||
|
||||
private static int DeleteEkzMk(SqlConnection connection, SqlTransaction transaction, int instrumentId)
|
||||
{
|
||||
return ExecuteScalarForInstrument(connection, transaction, @"
|
||||
DELETE FROM dbo.EKZMK
|
||||
WHERE IDEKZ = @InstrumentId;
|
||||
|
||||
SELECT @@ROWCOUNT;", instrumentId);
|
||||
}
|
||||
|
||||
private static int DeleteEkz(SqlConnection connection, SqlTransaction transaction, int id)
|
||||
{
|
||||
return ExecuteScalarForId(connection, transaction, @"
|
||||
DELETE FROM dbo.EKZ
|
||||
WHERE IDEKZ = @Id;
|
||||
|
||||
SELECT @@ROWCOUNT;", id);
|
||||
}
|
||||
|
||||
private static int ExecuteScalarForInstrument(SqlConnection connection, SqlTransaction transaction, string sql, int instrumentId)
|
||||
{
|
||||
using (var command = new SqlCommand(sql, connection, transaction))
|
||||
{
|
||||
command.CommandTimeout = ReferenceDirectorySqlHelpers.GetCommandTimeoutSeconds();
|
||||
command.Parameters.Add("@InstrumentId", SqlDbType.Int).Value = instrumentId;
|
||||
return Convert.ToInt32(command.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
|
||||
private static int ExecuteScalarForId(SqlConnection connection, SqlTransaction transaction, string sql, int id)
|
||||
{
|
||||
using (var command = new SqlCommand(sql, connection, transaction))
|
||||
{
|
||||
command.CommandTimeout = ReferenceDirectorySqlHelpers.GetCommandTimeoutSeconds();
|
||||
command.Parameters.Add("@Id", SqlDbType.Int).Value = id;
|
||||
return Convert.ToInt32(command.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
|
||||
private static List<int> ExecuteIdList(SqlConnection connection, SqlTransaction transaction, string sql, string parameterName, int parameterValue)
|
||||
{
|
||||
var result = new List<int>();
|
||||
using (var command = new SqlCommand(sql, connection, transaction))
|
||||
{
|
||||
command.CommandTimeout = ReferenceDirectorySqlHelpers.GetCommandTimeoutSeconds();
|
||||
command.Parameters.Add(parameterName, SqlDbType.Int).Value = parameterValue;
|
||||
|
||||
using (var reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(reader.GetInt32(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string NormalizeOptional(string value)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
|
||||
}
|
||||
|
||||
private static EkzDirectoryItem NormalizeEkzItem(EkzDirectoryItem item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new InvalidOperationException("Не переданы данные записи EKZ.");
|
||||
}
|
||||
|
||||
var normalizedItem = new EkzDirectoryItem
|
||||
{
|
||||
Id = item.Id,
|
||||
TypeSizeId = item.TypeSizeId,
|
||||
OwnerOrganizationId = item.OwnerOrganizationId,
|
||||
SerialNumber = NormalizeOptional(item.SerialNumber),
|
||||
InventoryNumber = NormalizeOptional(item.InventoryNumber),
|
||||
Notes = NormalizeOptional(item.Notes)
|
||||
};
|
||||
|
||||
if (normalizedItem.TypeSizeId <= 0)
|
||||
{
|
||||
throw new InvalidOperationException("Не указан типоразмер СИ.");
|
||||
}
|
||||
|
||||
if (normalizedItem.OwnerOrganizationId <= 0)
|
||||
{
|
||||
throw new InvalidOperationException("Не указана организация-владелец.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(normalizedItem.SerialNumber))
|
||||
{
|
||||
throw new InvalidOperationException("Не указан заводской номер.");
|
||||
}
|
||||
|
||||
if (normalizedItem.SerialNumber.Length > EkzDirectoryRules.SerialNumberMaxLength)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Заводской номер не должен превышать {0} символов.", EkzDirectoryRules.SerialNumberMaxLength));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(normalizedItem.InventoryNumber) && normalizedItem.InventoryNumber.Length > EkzDirectoryRules.InventoryNumberMaxLength)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Инвентарный номер не должен превышать {0} символов.", EkzDirectoryRules.InventoryNumberMaxLength));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(normalizedItem.Notes) && normalizedItem.Notes.Length > EkzDirectoryRules.NotesMaxLength)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Примечание не должно превышать {0} символов.", EkzDirectoryRules.NotesMaxLength));
|
||||
}
|
||||
|
||||
return normalizedItem;
|
||||
}
|
||||
|
||||
private static void EnsureEkzIsUnique(SqlConnection connection, int typeSizeId, int ownerOrganizationId, string serialNumber, int? excludeId)
|
||||
{
|
||||
const string sql = @"
|
||||
SELECT TOP (1) z.IDEKZ
|
||||
FROM dbo.EKZ z
|
||||
WHERE z.IDTPRZ = @TypeSizeId
|
||||
AND z.IDFRPDV = @OwnerOrganizationId
|
||||
AND z.NNZV = @SerialNumber
|
||||
AND ISNULL(z.IsDeleted, 0) = 0
|
||||
AND (@ExcludeId IS NULL OR z.IDEKZ <> @ExcludeId)
|
||||
ORDER BY z.IDEKZ DESC;";
|
||||
|
||||
using (var command = new SqlCommand(sql, connection))
|
||||
{
|
||||
command.CommandTimeout = ReferenceDirectorySqlHelpers.GetCommandTimeoutSeconds();
|
||||
command.Parameters.Add("@TypeSizeId", SqlDbType.Int).Value = typeSizeId;
|
||||
command.Parameters.Add("@OwnerOrganizationId", SqlDbType.Int).Value = ownerOrganizationId;
|
||||
command.Parameters.Add("@SerialNumber", SqlDbType.VarChar, EkzDirectoryRules.SerialNumberMaxLength).Value = serialNumber;
|
||||
ReferenceDirectorySqlHelpers.AddNullableIntParameter(command, "@ExcludeId", excludeId);
|
||||
|
||||
if (command.ExecuteScalar() != null)
|
||||
{
|
||||
throw new InvalidOperationException("Экземпляр с таким типоразмером, владельцем и заводским номером уже существует.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user