Files
XLAB/XLAB2/TipsEditWindowViewModel.cs
Курнат Андрей a47a7a5a3b edit
2026-03-19 23:31:41 +03:00

240 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
namespace XLAB2
{
internal sealed class TipsEditWindowViewModel : ObservableObject
{
private readonly IReadOnlyList<TipsDirectoryItem> _existingItems;
private int _categoryId;
private int _designId;
private int _instrumentNameId;
private bool? _isMkPrimaryOnly;
private bool? _isSpecialPurpose;
private int _measurementAreaId;
private string _metrControlCode;
private string _notes;
private string _registryPeriodMonthsText;
private string _registryTypeNumber;
private string _serviceLifeYearsText;
private string _typeName;
private string _validationMessage;
private string _vniimsTypeCodeText;
public TipsEditWindowViewModel(TipsDirectoryItem seed, bool isNew, IReadOnlyList<TipsDirectoryItem> existingItems, TypeSizeDirectoryService service)
{
var source = seed ?? new TipsDirectoryItem();
_existingItems = existingItems ?? Array.Empty<TipsDirectoryItem>();
Id = source.Id;
IsNew = isNew;
MeasurementAreas = service.LoadSpoiReferences();
InstrumentNames = service.LoadSpnmtpReferences();
Categories = WithEmpty(service.LoadSpktReferences());
Designs = WithEmpty(service.LoadSpkiReferences());
MeasurementAreaId = source.MeasurementAreaId;
InstrumentNameId = source.InstrumentNameId;
CategoryId = source.CategoryId ?? 0;
DesignId = source.DesignId ?? 0;
TypeName = source.TypeName ?? string.Empty;
ServiceLifeYearsText = source.ServiceLifeYears.HasValue ? source.ServiceLifeYears.Value.ToString() : string.Empty;
RegistryPeriodMonthsText = source.RegistryPeriodMonths.HasValue ? source.RegistryPeriodMonths.Value.ToString() : string.Empty;
RegistryTypeNumber = source.RegistryTypeNumber ?? string.Empty;
VniimsTypeCodeText = source.VniimsTypeCode.HasValue ? source.VniimsTypeCode.Value.ToString() : string.Empty;
MetrControlCode = source.MetrControlCode ?? string.Empty;
Notes = source.Notes ?? string.Empty;
IsSpecialPurpose = source.IsSpecialPurpose;
IsMkPrimaryOnly = source.IsMkPrimaryOnly;
ConfirmCommand = new RelayCommand(Confirm);
CancelCommand = new RelayCommand(Cancel);
}
public event EventHandler<bool?> CloseRequested;
public ICommand CancelCommand { get; private set; }
public IReadOnlyList<DirectoryLookupItem> Categories { get; private set; }
public ICommand ConfirmCommand { get; private set; }
public IReadOnlyList<DirectoryLookupItem> Designs { get; private set; }
public int Id { get; private set; }
public IReadOnlyList<DirectoryLookupItem> InstrumentNames { get; private set; }
public bool IsNew { get; private set; }
public IReadOnlyList<DirectoryLookupItem> MeasurementAreas { get; private set; }
public int MeasurementAreaId { get { return _measurementAreaId; } set { SetProperty(ref _measurementAreaId, value); } }
public int InstrumentNameId { get { return _instrumentNameId; } set { SetProperty(ref _instrumentNameId, value); } }
public int CategoryId { get { return _categoryId; } set { SetProperty(ref _categoryId, value); } }
public int DesignId { get { return _designId; } set { SetProperty(ref _designId, value); } }
public string TypeName { get { return _typeName; } set { SetProperty(ref _typeName, value); } }
public string ServiceLifeYearsText { get { return _serviceLifeYearsText; } set { SetProperty(ref _serviceLifeYearsText, value); } }
public string RegistryPeriodMonthsText { get { return _registryPeriodMonthsText; } set { SetProperty(ref _registryPeriodMonthsText, value); } }
public string RegistryTypeNumber { get { return _registryTypeNumber; } set { SetProperty(ref _registryTypeNumber, value); } }
public string VniimsTypeCodeText { get { return _vniimsTypeCodeText; } set { SetProperty(ref _vniimsTypeCodeText, value); } }
public string MetrControlCode { get { return _metrControlCode; } set { SetProperty(ref _metrControlCode, value); } }
public string Notes { get { return _notes; } set { SetProperty(ref _notes, value); } }
public bool? IsSpecialPurpose { get { return _isSpecialPurpose; } set { SetProperty(ref _isSpecialPurpose, value); } }
public bool? IsMkPrimaryOnly { get { return _isMkPrimaryOnly; } set { SetProperty(ref _isMkPrimaryOnly, value); } }
public string Title
{
get { return IsNew ? "Новый тип СИ" : "Редактирование типа СИ"; }
}
public string ValidationMessage
{
get { return _validationMessage; }
private set { SetProperty(ref _validationMessage, value); }
}
public TipsDirectoryItem ToResult()
{
return new TipsDirectoryItem
{
Id = Id,
MeasurementAreaId = MeasurementAreaId,
InstrumentNameId = InstrumentNameId,
CategoryId = CategoryId > 0 ? (int?)CategoryId : null,
DesignId = DesignId > 0 ? (int?)DesignId : null,
TypeName = Normalize(TypeName),
ServiceLifeYears = ParseNullableInt(ServiceLifeYearsText),
RegistryPeriodMonths = ParseNullableInt(RegistryPeriodMonthsText),
RegistryTypeNumber = Normalize(RegistryTypeNumber),
VniimsTypeCode = ParseNullableInt(VniimsTypeCodeText),
MetrControlCode = Normalize(MetrControlCode),
Notes = Normalize(Notes),
IsSpecialPurpose = IsSpecialPurpose,
IsMkPrimaryOnly = IsMkPrimaryOnly
};
}
private void Cancel(object parameter)
{
RaiseCloseRequested(false);
}
private void Confirm(object parameter)
{
if (MeasurementAreaId <= 0)
{
ValidationMessage = "Укажите область измерений.";
return;
}
if (InstrumentNameId <= 0)
{
ValidationMessage = "Укажите наименование типа СИ.";
return;
}
var normalizedTypeName = Normalize(TypeName);
if (string.IsNullOrWhiteSpace(normalizedTypeName))
{
ValidationMessage = "Укажите тип СИ.";
return;
}
if (normalizedTypeName.Length > TipsDirectoryRules.TypeNameMaxLength)
{
ValidationMessage = string.Format("Тип СИ не должен превышать {0} символов.", TipsDirectoryRules.TypeNameMaxLength);
return;
}
int? parsedValue;
if (!TryParseNullableInt(ServiceLifeYearsText, out parsedValue))
{
ValidationMessage = "Срок службы должен быть целым числом.";
return;
}
if (!TryParseNullableInt(RegistryPeriodMonthsText, out parsedValue))
{
ValidationMessage = "МПИ по Госреестру должен быть целым числом.";
return;
}
if (!TryParseNullableInt(VniimsTypeCodeText, out parsedValue))
{
ValidationMessage = "Код ВНИИМС должен быть целым числом.";
return;
}
var normalizedRegistryNumber = Normalize(RegistryTypeNumber);
if (!string.IsNullOrWhiteSpace(normalizedRegistryNumber) && normalizedRegistryNumber.Length > TipsDirectoryRules.RegistryTypeNumberMaxLength)
{
ValidationMessage = string.Format("Номер по Госреестру не должен превышать {0} символов.", TipsDirectoryRules.RegistryTypeNumberMaxLength);
return;
}
var normalizedMetrControlCode = Normalize(MetrControlCode);
if (!string.IsNullOrWhiteSpace(normalizedMetrControlCode) && normalizedMetrControlCode.Length > TipsDirectoryRules.MetrControlCodeMaxLength)
{
ValidationMessage = string.Format("Код АИС \"Метрконтроль\" не должен превышать {0} символов.", TipsDirectoryRules.MetrControlCodeMaxLength);
return;
}
var duplicate = _existingItems.FirstOrDefault(delegate(TipsDirectoryItem item)
{
return item != null
&& item.Id != Id
&& item.InstrumentNameId == InstrumentNameId
&& string.Equals(Normalize(item.TypeName), normalizedTypeName, StringComparison.OrdinalIgnoreCase);
});
if (duplicate != null)
{
ValidationMessage = string.Format("Тип СИ \"{0}\" уже существует для выбранного наименования типа СИ.", normalizedTypeName);
return;
}
ValidationMessage = string.Empty;
RaiseCloseRequested(true);
}
private static IReadOnlyList<DirectoryLookupItem> WithEmpty(IReadOnlyList<DirectoryLookupItem> source)
{
return new[] { new DirectoryLookupItem { Id = 0, Name = string.Empty } }.Concat(source ?? Array.Empty<DirectoryLookupItem>()).ToList();
}
private static string Normalize(string value)
{
return string.IsNullOrWhiteSpace(value) ? string.Empty : value.Trim();
}
private static int? ParseNullableInt(string value)
{
int? parsedValue;
return TryParseNullableInt(value, out parsedValue) ? parsedValue : (int?)null;
}
private static bool TryParseNullableInt(string value, out int? result)
{
if (string.IsNullOrWhiteSpace(value))
{
result = null;
return true;
}
int parsed;
if (int.TryParse(value.Trim(), out parsed))
{
result = parsed;
return true;
}
result = null;
return false;
}
private void RaiseCloseRequested(bool? dialogResult)
{
var handler = CloseRequested;
if (handler != null)
{
handler(this, dialogResult);
}
}
}
}