477 lines
16 KiB
C#
477 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Input;
|
|
|
|
namespace XLAB2
|
|
{
|
|
internal sealed class FrpdDirectoryWindowViewModel : ObservableObject
|
|
{
|
|
private readonly IFrpdDirectoryDialogService _dialogService;
|
|
private readonly FrpdDirectoryService _service;
|
|
private List<FrpdDirectoryItem> _frpdCache;
|
|
private bool _isBusy;
|
|
private string _searchText;
|
|
private FrpdDirectoryItem _selectedFrpd;
|
|
private FrpdvdDirectoryItem _selectedFrpdvd;
|
|
private string _statusText;
|
|
|
|
public FrpdDirectoryWindowViewModel(FrpdDirectoryService service, IFrpdDirectoryDialogService dialogService)
|
|
{
|
|
_service = service;
|
|
_dialogService = dialogService;
|
|
_frpdCache = new List<FrpdDirectoryItem>();
|
|
|
|
FrpdItems = new ObservableCollection<FrpdDirectoryItem>();
|
|
FrpdvdItems = new ObservableCollection<FrpdvdDirectoryItem>();
|
|
|
|
AddFrpdCommand = new RelayCommand(delegate { AddFrpdAsync(); }, delegate { return !IsBusy; });
|
|
EditFrpdCommand = new RelayCommand(delegate { EditFrpdAsync(); }, delegate { return !IsBusy && SelectedFrpd != null; });
|
|
DeleteFrpdCommand = new RelayCommand(delegate { DeleteFrpdAsync(); }, delegate { return !IsBusy && SelectedFrpd != null; });
|
|
AddFrpdvdCommand = new RelayCommand(delegate { AddFrpdvdAsync(); }, delegate { return !IsBusy && SelectedFrpd != null; });
|
|
EditFrpdvdCommand = new RelayCommand(delegate { EditFrpdvdAsync(); }, delegate { return !IsBusy && SelectedFrpdvd != null; });
|
|
DeleteFrpdvdCommand = new RelayCommand(delegate { DeleteFrpdvdAsync(); }, delegate { return !IsBusy && SelectedFrpdvd != null; });
|
|
RefreshCommand = new RelayCommand(delegate { RefreshAsync(); }, delegate { return !IsBusy; });
|
|
|
|
UpdateStatus();
|
|
}
|
|
|
|
public ICommand AddFrpdCommand { get; private set; }
|
|
public ICommand AddFrpdvdCommand { get; private set; }
|
|
public ICommand DeleteFrpdCommand { get; private set; }
|
|
public ICommand DeleteFrpdvdCommand { get; private set; }
|
|
public ICommand EditFrpdCommand { get; private set; }
|
|
public ICommand EditFrpdvdCommand { get; private set; }
|
|
public ObservableCollection<FrpdDirectoryItem> FrpdItems { get; private set; }
|
|
public ObservableCollection<FrpdvdDirectoryItem> FrpdvdItems { get; private set; }
|
|
public ICommand RefreshCommand { get; private set; }
|
|
|
|
public bool IsBusy
|
|
{
|
|
get { return _isBusy; }
|
|
private set
|
|
{
|
|
if (SetProperty(ref _isBusy, value))
|
|
{
|
|
RaiseCommandStates();
|
|
}
|
|
}
|
|
}
|
|
|
|
public string SearchText
|
|
{
|
|
get { return _searchText; }
|
|
set
|
|
{
|
|
if (SetProperty(ref _searchText, value))
|
|
{
|
|
ApplySearchFilter();
|
|
UpdateStatus();
|
|
}
|
|
}
|
|
}
|
|
|
|
public FrpdDirectoryItem SelectedFrpd
|
|
{
|
|
get { return _selectedFrpd; }
|
|
set
|
|
{
|
|
if (SetProperty(ref _selectedFrpd, value))
|
|
{
|
|
RaiseCommandStates();
|
|
LoadFrpdvdForSelection();
|
|
UpdateStatus();
|
|
}
|
|
}
|
|
}
|
|
|
|
public FrpdvdDirectoryItem SelectedFrpdvd
|
|
{
|
|
get { return _selectedFrpdvd; }
|
|
set
|
|
{
|
|
if (SetProperty(ref _selectedFrpdvd, value))
|
|
{
|
|
RaiseCommandStates();
|
|
UpdateStatus();
|
|
}
|
|
}
|
|
}
|
|
|
|
public string StatusText
|
|
{
|
|
get { return _statusText; }
|
|
private set { SetProperty(ref _statusText, value); }
|
|
}
|
|
|
|
public async Task InitializeAsync()
|
|
{
|
|
await ExecuteBusyOperationAsync(async delegate { await RefreshFrpdCoreAsync(null, null); });
|
|
}
|
|
|
|
private void AddFrpdAsync()
|
|
{
|
|
var result = _dialogService.ShowFrpdEditDialog(new FrpdDirectoryItem(), true, _frpdCache.ToList(), _service);
|
|
if (result == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RunMutationOperation(async delegate
|
|
{
|
|
var createdId = await Task.Run(delegate { return _service.AddFrpdItem(result); });
|
|
await RefreshFrpdCoreAsync(createdId, null);
|
|
_dialogService.ShowInfo("Запись FRPD добавлена.");
|
|
});
|
|
}
|
|
|
|
private void AddFrpdvdAsync()
|
|
{
|
|
if (SelectedFrpd == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var result = _dialogService.ShowFrpdvdEditDialog(new FrpdvdDirectoryItem { FrpdId = SelectedFrpd.Id }, true, FrpdvdItems.ToList(), _service);
|
|
if (result == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RunMutationOperation(async delegate
|
|
{
|
|
var createdId = await Task.Run(delegate { return _service.AddFrpdvdItem(result); });
|
|
await RefreshFrpdCoreAsync(result.FrpdId, createdId);
|
|
_dialogService.ShowInfo("Запись FRPDVD добавлена.");
|
|
});
|
|
}
|
|
|
|
private void ApplyFrpdFilter(int? preferredId)
|
|
{
|
|
var filteredItems = _frpdCache.Where(delegate(FrpdDirectoryItem item) { return MatchesSearch(item); }).ToList();
|
|
FrpdItems.Clear();
|
|
foreach (var item in filteredItems)
|
|
{
|
|
FrpdItems.Add(item);
|
|
}
|
|
|
|
SelectedFrpd = preferredId.HasValue
|
|
? FrpdItems.FirstOrDefault(delegate(FrpdDirectoryItem item) { return item.Id == preferredId.Value; })
|
|
: FrpdItems.FirstOrDefault();
|
|
}
|
|
|
|
private void ApplySearchFilter()
|
|
{
|
|
if (!IsBusy)
|
|
{
|
|
ApplyFrpdFilter(SelectedFrpd == null ? (int?)null : SelectedFrpd.Id);
|
|
}
|
|
}
|
|
|
|
private static FrpdDirectoryItem CloneFrpd(FrpdDirectoryItem source)
|
|
{
|
|
return new FrpdDirectoryItem
|
|
{
|
|
CreatedOn = source.CreatedOn,
|
|
Guid = source.Guid,
|
|
Id = source.Id,
|
|
LiquidatedOn = source.LiquidatedOn,
|
|
LocalCode = source.LocalCode,
|
|
Name = source.Name,
|
|
ParentId = source.ParentId,
|
|
ParentName = source.ParentName
|
|
};
|
|
}
|
|
|
|
private static FrpdvdDirectoryItem CloneFrpdvd(FrpdvdDirectoryItem source)
|
|
{
|
|
return new FrpdvdDirectoryItem
|
|
{
|
|
ActivityId = source.ActivityId,
|
|
ActivityName = source.ActivityName,
|
|
FrpdId = source.FrpdId,
|
|
Id = source.Id
|
|
};
|
|
}
|
|
|
|
private void DeleteFrpdAsync()
|
|
{
|
|
if (SelectedFrpd == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var selected = SelectedFrpd;
|
|
if (!_dialogService.Confirm(string.Format("Удалить организацию/подразделение \"{0}\"?", selected.Name)))
|
|
{
|
|
return;
|
|
}
|
|
|
|
RunMutationOperation(async delegate
|
|
{
|
|
var result = await Task.Run(delegate { return _service.DeleteFrpdItem(selected.Id); });
|
|
if (!result.IsDeleted)
|
|
{
|
|
_dialogService.ShowWarning(result.WarningMessage);
|
|
return;
|
|
}
|
|
|
|
await RefreshFrpdCoreAsync(null, null);
|
|
_dialogService.ShowInfo("Запись удалена.");
|
|
});
|
|
}
|
|
|
|
private void DeleteFrpdvdAsync()
|
|
{
|
|
if (SelectedFrpdvd == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var selected = SelectedFrpdvd;
|
|
if (!_dialogService.Confirm(string.Format("Удалить вид деятельности \"{0}\"?", selected.ActivityName)))
|
|
{
|
|
return;
|
|
}
|
|
|
|
RunMutationOperation(async delegate
|
|
{
|
|
var result = await Task.Run(delegate { return _service.DeleteFrpdvdItem(selected.Id); });
|
|
if (!result.IsDeleted)
|
|
{
|
|
_dialogService.ShowWarning(result.WarningMessage);
|
|
return;
|
|
}
|
|
|
|
await RefreshFrpdCoreAsync(selected.FrpdId, null);
|
|
_dialogService.ShowInfo("Запись удалена.");
|
|
});
|
|
}
|
|
|
|
private async Task ExecuteBusyOperationAsync(Func<Task> operation)
|
|
{
|
|
try
|
|
{
|
|
IsBusy = true;
|
|
await operation();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_dialogService.ShowError(ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
IsBusy = false;
|
|
}
|
|
}
|
|
|
|
private async Task ExecuteMutationOperationAsync(Func<Task> operation)
|
|
{
|
|
try
|
|
{
|
|
IsBusy = true;
|
|
await operation();
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
_dialogService.ShowWarning(ex.Message);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_dialogService.ShowError(ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
IsBusy = false;
|
|
}
|
|
}
|
|
|
|
private void EditFrpdAsync()
|
|
{
|
|
if (SelectedFrpd == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var result = _dialogService.ShowFrpdEditDialog(CloneFrpd(SelectedFrpd), false, _frpdCache.ToList(), _service);
|
|
if (result == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RunMutationOperation(async delegate
|
|
{
|
|
await Task.Run(delegate { _service.UpdateFrpdItem(result); });
|
|
await RefreshFrpdCoreAsync(result.Id, SelectedFrpdvd == null ? (int?)null : SelectedFrpdvd.Id);
|
|
_dialogService.ShowInfo("Запись обновлена.");
|
|
});
|
|
}
|
|
|
|
private void EditFrpdvdAsync()
|
|
{
|
|
if (SelectedFrpdvd == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var result = _dialogService.ShowFrpdvdEditDialog(CloneFrpdvd(SelectedFrpdvd), false, FrpdvdItems.ToList(), _service);
|
|
if (result == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RunMutationOperation(async delegate
|
|
{
|
|
await Task.Run(delegate { _service.UpdateFrpdvdItem(result); });
|
|
await RefreshFrpdCoreAsync(result.FrpdId, result.Id);
|
|
_dialogService.ShowInfo("Запись обновлена.");
|
|
});
|
|
}
|
|
|
|
private string[] GetSearchTokens()
|
|
{
|
|
return (SearchText ?? string.Empty)
|
|
.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(delegate(string token) { return token.Trim().ToUpperInvariant(); })
|
|
.Where(delegate(string token) { return token.Length > 0; })
|
|
.ToArray();
|
|
}
|
|
|
|
private void LoadFrpdvdForSelection()
|
|
{
|
|
if (!IsBusy)
|
|
{
|
|
RunBusyOperation(async delegate
|
|
{
|
|
if (SelectedFrpd == null)
|
|
{
|
|
FrpdvdItems.Clear();
|
|
SelectedFrpdvd = null;
|
|
UpdateStatus();
|
|
return;
|
|
}
|
|
|
|
await RefreshFrpdvdCoreAsync(SelectedFrpd.Id, null);
|
|
});
|
|
}
|
|
}
|
|
|
|
private bool MatchesSearch(FrpdDirectoryItem item)
|
|
{
|
|
if (item == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var tokens = GetSearchTokens();
|
|
if (tokens.Length == 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
var haystack = string.Join(
|
|
" ",
|
|
new[]
|
|
{
|
|
item.Id.ToString(),
|
|
item.Name,
|
|
item.ParentName,
|
|
item.LocalCode,
|
|
item.Guid,
|
|
item.ActivityNames
|
|
}
|
|
.Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); }))
|
|
.ToUpperInvariant();
|
|
return tokens.All(delegate(string token) { return haystack.IndexOf(token, StringComparison.Ordinal) >= 0; });
|
|
}
|
|
|
|
private async Task RefreshFrpdCoreAsync(int? frpdIdToSelect, int? frpdvdIdToSelect)
|
|
{
|
|
var currentFrpdId = SelectedFrpd == null ? (int?)null : SelectedFrpd.Id;
|
|
_frpdCache = (await Task.Run(delegate { return _service.LoadFrpdItems(); })).ToList();
|
|
|
|
ApplyFrpdFilter(frpdIdToSelect.HasValue ? frpdIdToSelect : currentFrpdId);
|
|
if (SelectedFrpd == null)
|
|
{
|
|
FrpdvdItems.Clear();
|
|
SelectedFrpdvd = null;
|
|
UpdateStatus();
|
|
return;
|
|
}
|
|
|
|
await RefreshFrpdvdCoreAsync(SelectedFrpd.Id, frpdvdIdToSelect);
|
|
UpdateStatus();
|
|
}
|
|
|
|
private async Task RefreshFrpdvdCoreAsync(int frpdId, int? frpdvdIdToSelect)
|
|
{
|
|
var items = await Task.Run(delegate { return _service.LoadFrpdvdItems(frpdId); });
|
|
FrpdvdItems.Clear();
|
|
foreach (var item in items)
|
|
{
|
|
FrpdvdItems.Add(item);
|
|
}
|
|
|
|
SelectedFrpdvd = frpdvdIdToSelect.HasValue
|
|
? FrpdvdItems.FirstOrDefault(delegate(FrpdvdDirectoryItem item) { return item.Id == frpdvdIdToSelect.Value; })
|
|
: FrpdvdItems.FirstOrDefault();
|
|
UpdateStatus();
|
|
}
|
|
|
|
private void RaiseCommandStates()
|
|
{
|
|
((RelayCommand)AddFrpdCommand).RaiseCanExecuteChanged();
|
|
((RelayCommand)EditFrpdCommand).RaiseCanExecuteChanged();
|
|
((RelayCommand)DeleteFrpdCommand).RaiseCanExecuteChanged();
|
|
((RelayCommand)AddFrpdvdCommand).RaiseCanExecuteChanged();
|
|
((RelayCommand)EditFrpdvdCommand).RaiseCanExecuteChanged();
|
|
((RelayCommand)DeleteFrpdvdCommand).RaiseCanExecuteChanged();
|
|
((RelayCommand)RefreshCommand).RaiseCanExecuteChanged();
|
|
}
|
|
|
|
private void RefreshAsync()
|
|
{
|
|
RunBusyOperation(async delegate { await RefreshFrpdCoreAsync(SelectedFrpd == null ? (int?)null : SelectedFrpd.Id, SelectedFrpdvd == null ? (int?)null : SelectedFrpdvd.Id); });
|
|
}
|
|
|
|
private async void RunBusyOperation(Func<Task> operation)
|
|
{
|
|
try
|
|
{
|
|
await ExecuteBusyOperationAsync(operation);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
IsBusy = false;
|
|
_dialogService.ShowError(ex.Message);
|
|
}
|
|
}
|
|
|
|
private async void RunMutationOperation(Func<Task> operation)
|
|
{
|
|
try
|
|
{
|
|
await ExecuteMutationOperationAsync(operation);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
IsBusy = false;
|
|
_dialogService.ShowError(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void UpdateStatus()
|
|
{
|
|
var searchText = string.IsNullOrWhiteSpace(SearchText) ? null : SearchText.Trim();
|
|
StatusText = string.Format(
|
|
"{0}Подразделений: {1}/{2}. Видов деятельности: {3}.",
|
|
string.IsNullOrWhiteSpace(searchText) ? string.Empty : string.Format("Поиск: \"{0}\". ", searchText),
|
|
FrpdItems.Count,
|
|
_frpdCache.Count,
|
|
FrpdvdItems.Count);
|
|
}
|
|
}
|
|
}
|