semesterWork/Presence.Desktop/ViewModels/GroupViewModel.cs
2024-12-12 21:16:01 +03:00

293 lines
9.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Avalonia.Controls;
using domain.Request;
using domain.UseCase;
using Presense.Desktop.Models;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Presence.Desktop.ViewModels
{
public class GroupViewModel : ViewModelBase
{
private readonly IGroupUseCase _groupService;
private readonly List<GroupPresenter> _groupPresentersDataSource = new();
private ObservableCollection<GroupPresenter> _groups;
public ObservableCollection<GroupPresenter> Groups => _groups;
private GroupPresenter? _selectedGroupItem;
public GroupPresenter? SelectedGroupItem
{
get => _selectedGroupItem;
set
{
if (_selectedGroupItem != value)
{
_selectedGroupItem = value;
this.RaisePropertyChanged();
UpdateStudents();
}
}
}
private ObservableCollection<StudentPresenter> _students;
public ObservableCollection<StudentPresenter> Students => _students;
public GroupViewModel() : this(null!) { }
public GroupViewModel(IGroupUseCase groupUseCase)
{
_groupService = groupUseCase;
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
ImportStudentsCommand = ReactiveCommand.CreateFromTask(ImportStudentsAsync);
LoadGroupsAndStudents();
_students = new ObservableCollection<StudentPresenter>();
RemoveAllStudentsCommand = ReactiveCommand.Create(RemoveAllStudents);
RemoveSelectedStudentsCommand = ReactiveCommand.Create(RemoveSelectedStudents);
}
private void LoadGroupsAndStudents()
{
foreach (var groupEntity in _groupService.GetGroupsWithStudents())
{
var groupPresenter = new GroupPresenter
{
GroupId = groupEntity.GroupId,
GroupName = groupEntity.GroupName,
Students = groupEntity.Students?.Select(student => new StudentPresenter
{
Id = student.Id,
FirstName = student.FirstName,
LastName = student.LastName,
Patronymic = student.Patronymic,
Group = null
}).ToList(),
Subjects = groupEntity.Subjects.Select(subject => new SubjectPresenter
{
SubjectId = subject.SubjectId,
SubjectName = subject.SubjectName
}).ToList()
};
foreach (var student in groupPresenter.Students ?? Enumerable.Empty<StudentPresenter>())
{
student.Group = groupPresenter;
}
_groupPresentersDataSource.Add(groupPresenter);
}
_groups = new ObservableCollection<GroupPresenter>(_groupPresentersDataSource);
}
private void UpdateStudents()
{
if (SelectedGroupItem?.Students == null) return;
Students.Clear();
foreach (var student in SelectedGroupItem.Students)
{
Students.Add(student);
}
}
private readonly string[] _sortingOptions = new[]
{
"Без сортировки",
"Фамилии (по возрастанию)",
"Фамилии (по убыванию)"
};
public string[] SortingOptions => _sortingOptions;
private string? _selectedSortingOption;
public string? SelectedSortingOption
{
get => _selectedSortingOption;
set
{
this.RaiseAndSetIfChanged(ref _selectedSortingOption, value);
ApplySorting();
}
}
private void ApplySorting()
{
if (SelectedGroupItem?.Students == null) return;
IEnumerable<StudentPresenter> sortedStudents = SelectedSortingOption switch
{
"Фамилии (по возрастанию)" => SelectedGroupItem.Students.OrderBy(s => s.LastName),
"Фамилии (по убыванию)" => SelectedGroupItem.Students.OrderByDescending(s => s.LastName),
_ => SelectedGroupItem.Students
};
Students.Clear();
foreach (var student in sortedStudents)
{
Students.Add(student);
}
}
public ReactiveCommand<Unit, Unit> RemoveAllStudentsCommand { get; }
private void RemoveAllStudents()
{
if (SelectedGroupItem == null || SelectedGroupItem.Students == null) return;
_groupService.RemoveStudentsFromGroup(SelectedGroupItem.GroupId);
SelectedGroupItem.Students.Clear();
UpdateStudents();
LoadGroupsAndStudents();
}
public ReactiveCommand<Unit, Unit> ImportStudentsCommand { get; }
public async Task ImportStudentsAsync()
{
var dialog = new OpenFileDialog
{
Title = "Выберите файл CSV:",
Filters = new List<FileDialogFilter>
{
new FileDialogFilter { Name = "CSV Files", Extensions = { "csv" } }
}
};
var result = await dialog.ShowAsync(new Window());
if (result != null && result.Any())
{
var filePath = result.First();
if (SelectedGroupItem == null)
{
Console.WriteLine("Группа не выбрана.");
return;
}
try
{
var csvLines = File.ReadAllLines(filePath, Encoding.GetEncoding("windows-1251"));
var studentsToAdd = new List<AddStudentRequest>();
foreach (var line in csvLines)
{
var data = line.Split(';');
if (data.Length != 3)
{
Console.WriteLine($"Либо разделитель либо хз: {line}");
continue;
}
studentsToAdd.Add(new AddStudentRequest
{
FirstName = data[0],
LastName = data[1],
Patronymic = data[2]
});
}
if (studentsToAdd.Any())
{
_groupService.AddStudentsToGroup(SelectedGroupItem.GroupId, studentsToAdd);
foreach (var studentRequest in studentsToAdd)
{
var studentPresenter = new StudentPresenter
{
FirstName = studentRequest.FirstName,
LastName = studentRequest.LastName,
Patronymic = studentRequest.Patronymic,
Group = SelectedGroupItem
};
SelectedGroupItem.Students.Add(studentPresenter);
Students.Add(studentPresenter);
}
UpdateStudents();
LoadGroupsAndStudents();
}
else
{
Console.WriteLine("Проблема с данными.");
}
}
catch (Exception ex)
{
Console.WriteLine($"...: {ex.Message}");
}
}
}
private ObservableCollection<StudentPresenter> _selectedStudents = new();
public ObservableCollection<StudentPresenter> SelectedStudents
{
get => _selectedStudents;
set
{
this.RaiseAndSetIfChanged(ref _selectedStudents, value);
UpdateSelectionStates();
}
}
private bool _isSingleSelection;
public bool IsSingleSelection
{
get => _isSingleSelection;
set => this.RaiseAndSetIfChanged(ref _isSingleSelection, value);
}
private bool _isMultipleSelection;
public bool IsMultipleSelection
{
get => _isMultipleSelection;
set => this.RaiseAndSetIfChanged(ref _isMultipleSelection, value);
}
public void UpdateSelectionStates()
{
IsSingleSelection = SelectedStudents.Count == 1;
IsMultipleSelection = SelectedStudents.Count > 1;
}
public ReactiveCommand<Unit, Unit> RemoveSelectedStudentsCommand { get; }
private void RemoveSelectedStudents()
{
if (SelectedStudents == null || SelectedStudents.Count == 0) return;
var studentIds = SelectedStudents.Select(s => s.Id).ToList();
_groupService.RemoveStudentsFromGroupByIds(SelectedGroupItem.GroupId, studentIds);
foreach (var student in SelectedStudents.ToList())
{
SelectedGroupItem.Students.Remove(student);
Students.Remove(student);
}
UpdateStudents();
LoadGroupsAndStudents();
}
}
}