using System; using System.Collections.Generic; using System.Linq; using System.Windows.Input; namespace XLAB2 { internal sealed class PrfrEditWindowViewModel : ObservableObject { private readonly IReadOnlyList _existingItems; private string _guid; private bool? _isPinAuth; private int _organizationId; private string _personnelNumber; private string _pinChangedAtText; private string _pinHash; private int _positionId; private string _validationMessage; public PrfrEditWindowViewModel(PrfrDirectoryItem seed, bool isNew, IReadOnlyList existingItems, PrsnDirectoryService service) { var source = seed ?? new PrfrDirectoryItem(); _existingItems = existingItems ?? Array.Empty(); EmploymentId = source.EmploymentId; PersonId = source.PersonId; IsNew = isNew; OrganizationItems = service.LoadFrpdReferences(); PositionItems = new[] { new DirectoryLookupItem { Id = 0, Name = string.Empty } } .Concat(service.LoadSpdlReferences() ?? Array.Empty()) .ToList(); OrganizationId = source.OrganizationId; PositionId = source.PositionId.HasValue ? source.PositionId.Value : 0; HireDate = source.HireDate; DismissalDate = source.DismissalDate; PositionStartDate = source.PositionStartDate; QualificationPlanDate = source.QualificationPlanDate; LastVacationStartDate = source.LastVacationStartDate; LastVacationEndDate = source.LastVacationEndDate; NextVacationStartDate = source.NextVacationStartDate; NextVacationEndDate = source.NextVacationEndDate; PersonnelNumber = source.PersonnelNumber ?? string.Empty; Guid = source.Guid ?? string.Empty; PinHash = source.PinHash ?? string.Empty; PinChangedAtText = source.PinChangedAt.HasValue ? source.PinChangedAt.Value.ToString("dd.MM.yyyy HH:mm") : string.Empty; IsPinAuth = source.IsPinAuth; ConfirmCommand = new RelayCommand(Confirm); CancelCommand = new RelayCommand(Cancel); } public event EventHandler CloseRequested; public ICommand CancelCommand { get; private set; } public ICommand ConfirmCommand { get; private set; } public DateTime? DismissalDate { get; set; } public int EmploymentId { get; private set; } public string Guid { get { return _guid; } set { SetProperty(ref _guid, value); } } public DateTime? HireDate { get; set; } public bool? IsPinAuth { get { return _isPinAuth; } set { SetProperty(ref _isPinAuth, value); } } public bool IsNew { get; private set; } public DateTime? LastVacationEndDate { get; set; } public DateTime? LastVacationStartDate { get; set; } public DateTime? NextVacationEndDate { get; set; } public DateTime? NextVacationStartDate { get; set; } public int OrganizationId { get { return _organizationId; } set { SetProperty(ref _organizationId, value); } } public IReadOnlyList OrganizationItems { get; private set; } public int PersonId { get; private set; } public string PersonnelNumber { get { return _personnelNumber; } set { SetProperty(ref _personnelNumber, value); } } public string PinChangedAtText { get { return _pinChangedAtText; } set { SetProperty(ref _pinChangedAtText, value); } } public string PinHash { get { return _pinHash; } set { SetProperty(ref _pinHash, value); } } public int PositionId { get { return _positionId; } set { SetProperty(ref _positionId, value); } } public IReadOnlyList PositionItems { get; private set; } public DateTime? PositionStartDate { get; set; } public DateTime? QualificationPlanDate { get; set; } public string Title { get { return IsNew ? "Новая запись персонала в организации" : "Редактирование записи персонала в организации"; } } public string ValidationMessage { get { return _validationMessage; } private set { SetProperty(ref _validationMessage, value); } } public PrfrDirectoryItem ToResult() { return new PrfrDirectoryItem { DismissalDate = DismissalDate, EmploymentId = EmploymentId, Guid = NormalizeNullable(Guid), HireDate = HireDate, IsPinAuth = IsPinAuth, LastVacationEndDate = LastVacationEndDate, LastVacationStartDate = LastVacationStartDate, NextVacationEndDate = NextVacationEndDate, NextVacationStartDate = NextVacationStartDate, OrganizationId = OrganizationId, PersonId = PersonId, PersonnelNumber = NormalizeNullable(PersonnelNumber), PinChangedAt = ParseNullableDateTime(PinChangedAtText), PinHash = NormalizeNullable(PinHash), PositionId = PositionId > 0 ? (int?)PositionId : null, PositionStartDate = PositionStartDate, QualificationPlanDate = QualificationPlanDate }; } private void Cancel(object parameter) { RaiseCloseRequested(false); } private void Confirm(object parameter) { var normalizedPersonnelNumber = NormalizeNullable(PersonnelNumber); var normalizedGuid = NormalizeNullable(Guid); DateTime? pinChangedAt; if (OrganizationId <= 0) { ValidationMessage = "Укажите организацию/подразделение."; return; } if (normalizedPersonnelNumber != null && normalizedPersonnelNumber.Length > PrfrDirectoryRules.PersonnelNumberMaxLength) { ValidationMessage = string.Format("Табельный номер не должен превышать {0} символов.", PrfrDirectoryRules.PersonnelNumberMaxLength); return; } if (normalizedGuid != null && normalizedGuid.Length > PrfrDirectoryRules.GuidMaxLength) { ValidationMessage = string.Format("GUID сотрудника не должен превышать {0} символов.", PrfrDirectoryRules.GuidMaxLength); return; } if (!TryParseNullableDateTime(PinChangedAtText, out pinChangedAt)) { ValidationMessage = "Дата/время изменения PIN указаны в неверном формате."; return; } var duplicate = _existingItems.FirstOrDefault(delegate(PrfrDirectoryItem item) { return item != null && item.EmploymentId != EmploymentId && item.OrganizationId == OrganizationId; }); if (duplicate != null) { ValidationMessage = "Такая связка персоны и организации уже существует в справочнике."; return; } ValidationMessage = string.Empty; RaiseCloseRequested(true); } private string NormalizeNullable(string value) { return string.IsNullOrWhiteSpace(value) ? null : value.Trim(); } private DateTime? ParseNullableDateTime(string value) { DateTime? result; return TryParseNullableDateTime(value, out result) ? result : null; } private bool TryParseNullableDateTime(string value, out DateTime? result) { if (string.IsNullOrWhiteSpace(value)) { result = null; return true; } DateTime parsedValue; if (DateTime.TryParse(value.Trim(), out parsedValue)) { result = parsedValue; return true; } result = null; return false; } private void RaiseCloseRequested(bool? dialogResult) { var handler = CloseRequested; if (handler != null) { handler(this, dialogResult); } } } }