Compare commits

...

5 Commits

80 changed files with 464 additions and 67 deletions

View File

@ -6,5 +6,6 @@
<Application.Styles> <Application.Styles>
<FluentTheme /> <FluentTheme />
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

View File

@ -7,6 +7,7 @@ using presence.data.RemoteData.RemoteDataBase;
using presence.data.Repository; using presence.data.Repository;
using presence.domain.UseCase; using presence.domain.UseCase;
using Presence.Desktop.ViewModels; using Presence.Desktop.ViewModels;
using ReactiveUI;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -21,9 +22,17 @@ namespace Presence.Desktop.DI
public static void AddCommonService(this IServiceCollection collection) { public static void AddCommonService(this IServiceCollection collection) {
collection collection
.AddDbContext<RemoteDataBaseContext>() .AddDbContext<RemoteDataBaseContext>()
.AddSingleton<IGroupRepository, SQLGroupRepositoryImpl>() .AddSingleton<IGroupRepository, SQLGroupRepositoryImpl>()
.AddSingleton<IUserRepository, SQLUserRepositoryImpl>()
.AddSingleton<IPresenceRepository, SQLPresenceRepositoryImpl>()
.AddSingleton<PresenceUseCase>()
.AddSingleton<UserUseCase>()
.AddTransient<GroupUseCase>()
.AddTransient<IGroupUseCase, GroupService>() .AddTransient<IGroupUseCase, GroupService>()
.AddTransient<GroupViewModel>(); .AddTransient<GroupViewModel>()
.AddTransient<PresenceViewModel>();
;
} }
} }
} }

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Presence.Desktop.Models
{
public class PresencePresenter
{
public int Id { get; set; }
public DateOnly Date { get; set; }
public int ClassNumber { get; set; }
public bool IsAttendence { get; set; }
public UserPresenter? User { get; set; }
}
}

View File

@ -11,5 +11,6 @@ namespace Presence.Desktop.Models
public int Id{ get; set; } public int Id{ get; set; }
public string Name { get; set; } public string Name { get; set; }
public GroupPresenter Group { get; set; } public GroupPresenter Group { get; set; }
public PresencePresenter Presence { get; set; }
} }
} }

View File

@ -15,6 +15,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.2.1" /> <PackageReference Include="Avalonia" Version="11.2.1" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.2.1" />
<PackageReference Include="Avalonia.Desktop" Version="11.2.1" /> <PackageReference Include="Avalonia.Desktop" Version="11.2.1" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.1" /> <PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.1" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.1" /> <PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.1" />

View File

@ -10,12 +10,21 @@ using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Tmds.DBus.Protocol; using Avalonia.Controls.Selection;
using presence.data.RemoteData.RemoteDataBase;
using presence.data.Repository;
using presence.domain.UseCase;
using System.Reactive;
using Splat;
namespace Presence.Desktop.ViewModels namespace Presence.Desktop.ViewModels
{ {
public class GroupViewModel : ViewModelBase, IRoutableViewModel public class GroupViewModel : ViewModelBase, IRoutableViewModel
{ {
public string? UrlPathSegment { get; }
public IScreen HostScreen { get; }
private readonly PresenceUseCase _presenceUseCase;
public ICommand OpenFileDialog { get; } public ICommand OpenFileDialog { get; }
public Interaction<string?, string?> SelectFileInteraction => _SelectFileInteraction; public Interaction<string?, string?> SelectFileInteraction => _SelectFileInteraction;
public readonly Interaction<string?, string?> _SelectFileInteraction; public readonly Interaction<string?, string?> _SelectFileInteraction;
@ -34,6 +43,10 @@ namespace Presence.Desktop.ViewModels
get => _selectedGroupItem; get => _selectedGroupItem;
set => this.RaiseAndSetIfChanged(ref _selectedGroupItem, value); } set => this.RaiseAndSetIfChanged(ref _selectedGroupItem, value); }
private bool _MultipleSelected = false;
public bool MultipleSelected { get => _MultipleSelected; set => this.RaiseAndSetIfChanged(ref _MultipleSelected, value); }
public SelectionModel<UserPresenter> Selection { get; }
private GroupPresenter? _selectedGroupItem; private GroupPresenter? _selectedGroupItem;
@ -41,29 +54,22 @@ namespace Presence.Desktop.ViewModels
private IGroupUseCase _groupUseCase; private IGroupUseCase _groupUseCase;
public ObservableCollection<UserPresenter> Users { get => _users;} public ObservableCollection<UserPresenter> Users { get => _users;}
public ObservableCollection<UserPresenter> _users; public ObservableCollection<UserPresenter> _users;
public GroupViewModel(IGroupUseCase groupUseCase) public ICommand RemoveUserCommand { get; }
{ public ICommand EditUserCommand { get; }
foreach (var item in groupUseCase.GetGroupsWithStudents()) public ICommand RemoveAllSelectedCommand { get; }
{ public ReactiveCommand<Unit, Unit> NavigateToPresenceCommand { get; }
GroupPresenter groupPresenter = new GroupPresenter
{
Id = item.Id,
Name = item.Name,
Users = item.User?.Select(user => new UserPresenter
{
Name = user.FIO,
Id = user.Id,
Group = new GroupPresenter { Id = item.Id, Name = item.Name }
}
).ToList()
};
_groupPresentersDataSource.Add(groupPresenter);
}
_groups = new ObservableCollection<GroupPresenter>(_groupPresentersDataSource);
public GroupViewModel(IGroupUseCase groupUseCase, PresenceUseCase presenceUseCase, IScreen? screen = null)
{
HostScreen = screen ?? Locator.Current.GetService<IScreen>()!;
_groupUseCase = groupUseCase; _groupUseCase = groupUseCase;
_presenceUseCase = presenceUseCase;
_SelectFileInteraction = new Interaction<string?, string?>(); _SelectFileInteraction = new Interaction<string?, string?>();
OpenFileDialog = ReactiveCommand.CreateFromTask(SelectFile); OpenFileDialog = ReactiveCommand.CreateFromTask(SelectFile);
_groups = new ObservableCollection<GroupPresenter>(_groupPresentersDataSource);
_users = new ObservableCollection<UserPresenter>(); _users = new ObservableCollection<UserPresenter>();
RefreshGroups(); RefreshGroups();
@ -73,6 +79,14 @@ namespace Presence.Desktop.ViewModels
RefreshGroups(); RefreshGroups();
SetUsers(); SetUsers();
}); });
Selection = new SelectionModel<UserPresenter>();
Selection.SingleSelect = false;
Selection.SelectionChanged += SelectionChanged;
RemoveUserCommand = ReactiveCommand.Create<UserPresenter>(RemoveUser);
EditUserCommand = ReactiveCommand.Create<UserPresenter>(EditUser);
RemoveAllSelectedCommand = ReactiveCommand.Create(RemoveAllSelected);
NavigateToPresenceCommand = ReactiveCommand.Create(NavigateToPresence);
} }
private void SetUsers() private void SetUsers()
@ -88,7 +102,6 @@ namespace Presence.Desktop.ViewModels
} }
} }
private void RefreshGroups() private void RefreshGroups()
{ {
_groupPresentersDataSource.Clear(); _groupPresentersDataSource.Clear();
@ -110,13 +123,56 @@ namespace Presence.Desktop.ViewModels
} }
_groups = new ObservableCollection<GroupPresenter>(_groupPresentersDataSource); _groups = new ObservableCollection<GroupPresenter>(_groupPresentersDataSource);
} }
public string? UrlPathSegment { get; }
public IScreen HostScreen { get; } void SelectionChanged(object sender, SelectionModelSelectionChangedEventArgs e)
{
MultipleSelected = Selection.SelectedItems.Count > 1;
}
private async Task SelectFile() private async Task SelectFile()
{ {
Console.WriteLine("clock"); Console.WriteLine("clock");
SelectedFile = await _SelectFileInteraction.Handle("Chose csv file"); SelectedFile = await _SelectFileInteraction.Handle("Chose csv file");
} }
private void RemoveUser(UserPresenter user)
{
if (user == null || SelectedGroupItem == null) return;
_groupUseCase.RemoveUserFromGroup(user.Id);
RefreshGroups();
SetUsers();
}
private void EditUser(UserPresenter user)
{
if (user == null) return;
// TODO: Добавить логику редактирования пользователя
// Можно реализовать через диалоговое окно или навигацию на форму редактирования
}
private void RemoveAllSelected()
{
if (SelectedGroupItem == null) return;
var selectedUsers = Selection.SelectedItems.ToList();
foreach (var user in selectedUsers)
{
_groupUseCase.RemoveUserFromGroup(user.Id);
}
RefreshGroups();
SetUsers();
}
private void NavigateToPresence()
{
var groupRepository = new SQLGroupRepositoryImpl(new RemoteDataBaseContext());
var groupUseCase = new GroupUseCase(groupRepository);
// Добавляем логику навигации к PresenceViewModel
var presenceViewModel = new PresenceViewModel(groupUseCase, _presenceUseCase);
HostScreen.Router.Navigate.Execute(presenceViewModel);
}
} }
} }

View File

@ -2,7 +2,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using domain.UseCase;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using presence.data.RemoteData.RemoteDataBase;
using presence.domain.UseCase;
using ReactiveUI; using ReactiveUI;
namespace Presence.Desktop.ViewModels namespace Presence.Desktop.ViewModels
@ -13,8 +16,10 @@ namespace Presence.Desktop.ViewModels
public MainWindowViewModel(IServiceProvider serviceProvider) public MainWindowViewModel(IServiceProvider serviceProvider)
{ {
var groupViewModel = serviceProvider.GetRequiredService<GroupViewModel>(); var iGroupUseCase = serviceProvider.GetRequiredService<IGroupUseCase>();
Router.Navigate.Execute(groupViewModel); var presenceUseCase = serviceProvider.GetRequiredService<PresenceUseCase>();
Router.Navigate.Execute(new GroupViewModel(iGroupUseCase, presenceUseCase, this));
} }
} }
} }

View File

@ -1,13 +1,139 @@
using Avalonia.Data.Converters;
using presence.data.RemoteData.RemoteDataBase.DAO;
using presence.domain.Models;
using presence.domain.UseCase;
using Presence.Desktop.Models;
using Presence.Desktop.ViewModels;
using ReactiveUI; using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Reactive;
namespace Presence.Desktop.ViewModels; namespace Presence.Desktop.ViewModels
{
public class PresenceViewModel : ViewModelBase, IRoutableViewModel public class PresenceViewModel : ViewModelBase, IRoutableViewModel
{ {
public string? UrlPathSegment { get; } public string? UrlPathSegment { get; } = "Presence";
public IScreen HostScreen { get; } public IScreen HostScreen { get; }
private readonly GroupUseCase _groupUseCase;
private readonly PresenceUseCase _presenceUseCase;
public ObservableCollection<PresencePresenter> AttendanceRecords { get; set; } = new();
public ObservableCollection<GroupPresenter> Groups { get; set; } = new();
private ObservableCollection<PresencePresenter> _selectedItems = new();
public ObservableCollection<PresencePresenter> SelectedItems
{
get => _selectedItems;
set => this.RaiseAndSetIfChanged(ref _selectedItems, value);
}
private GroupPresenter? _selectedGroup;
public GroupPresenter? SelectedGroup
{
get => _selectedGroup;
set
{
this.RaiseAndSetIfChanged(ref _selectedGroup, value);
FilterAttendanceRecords();
}
}
private List<DateTime?> _selectedDate = new List<DateTime?>();
public List<DateTime?> SelectedDate
{
get => _selectedDate;
set
{
this.RaiseAndSetIfChanged(ref _selectedDate, value);
FilterAttendanceRecords();
}
}
public ReactiveCommand<Unit, Unit> NavigateBackCommand { get; }
public ReactiveCommand<Unit, Unit> DeleteSelectedPresenceCommand { get; }
public PresenceViewModel(GroupUseCase groupUseCase, PresenceUseCase presenceUseCase)
{
_groupUseCase = groupUseCase;
_presenceUseCase = presenceUseCase;
NavigateBackCommand = ReactiveCommand.Create(() => { });
DeleteSelectedPresenceCommand = ReactiveCommand.Create(DeleteSelectedItems);
LoadGroups();
}
private void LoadGroups()
{
Groups.Clear();
var groups = _groupUseCase.GetAllGroups();
foreach (var group in groups)
{
Groups.Add(new GroupPresenter
{
Id = group.Id,
Name = group.Name
});
}
}
public void FilterAttendanceRecords()
{
if (SelectedGroup == null || SelectedDate == null)
{
AttendanceRecords.Clear();
return;
}
AttendanceRecords.Clear();
foreach (var selDate in SelectedDate)
{
var records = _presenceUseCase.GetPresenceByGroupAndDate(
SelectedGroup.Id,
DateOnly.FromDateTime(selDate.Value));
foreach (var record in records)
{
AttendanceRecords.Add(new PresencePresenter
{
Id = record.Id,
Date = record.Date,
ClassNumber = record.ClassNumber,
IsAttendence = record.IsAttendence,
User = new UserPresenter
{
Id = record.User.Id,
Name = record.User.FIO
}
});
}
} }
// Логирование для отладки
Console.WriteLine($"Загружено записей посещаемости: {AttendanceRecords.Count}");
}
private void DeleteSelectedItems()
{
if (SelectedItems.Any())
{
foreach (var item in SelectedItems.ToList())
{
_presenceUseCase.DeletePresenceByClassNumberAndDateAndUserId(item.ClassNumber, item.Date, item.User.Id); // Удаляем из базы данных
AttendanceRecords.Remove(item); // Удаляем из коллекции
}
}
}
}
}

View File

@ -13,6 +13,16 @@
<DockPanel Background="Azure"> <DockPanel Background="Azure">
<StackPanel DockPanel.Dock="Bottom"> <StackPanel DockPanel.Dock="Bottom">
<TextBlock Text="List ↑" HorizontalAlignment="Center"/> <TextBlock Text="List ↑" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding Users.Count, StringFormat='Количество студентов: {0}'}"
HorizontalAlignment="Left"
Margin="10,10,0,0"
Foreground="Black"
IsVisible="{Binding SelectedGroupItem, Converter={x:Static ObjectConverters.IsNotNull}}"/>
<Button Content="Перейти к посещаемости"
Command="{Binding NavigateToPresenceCommand}"
HorizontalAlignment="Right"
Margin="0,10,0,0"
Foreground="Black"/>
</StackPanel> </StackPanel>
<StackPanel <StackPanel
Spacing="10" Spacing="10"
@ -31,7 +41,28 @@
<ComboBox/> <ComboBox/>
</StackPanel> </StackPanel>
<Border> <Border>
<ListBox Background="Bisque" ItemsSource="{Binding Users}"> <ListBox SelectionMode="Multiple" Selection="{Binding Selection}" Background="Bisque" ItemsSource="{Binding Users}">
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem
IsVisible="{Binding !MultipleSelected}"
Header="Remove"
Command="{Binding RemoveUserCommand}"
CommandParameter="{Binding Selection.SelectedItem}"
Foreground="Black"/>
<MenuItem
IsVisible="{Binding !MultipleSelected}"
Header="Edit"
Command="{Binding EditUserCommand}"
CommandParameter="{Binding Selection.SelectedItem}"
Foreground="Black"/>
<MenuItem
IsVisible="{Binding MultipleSelected}"
Header="RemoveAll"
Command="{Binding RemoveAllSelectedCommand}"
Foreground="Black"/>
</ContextMenu>
</ListBox.ContextMenu>
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">

View File

@ -1,5 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Platform.Storage;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using Presence.Desktop.ViewModels; using Presence.Desktop.ViewModels;
using ReactiveUI; using ReactiveUI;
@ -10,8 +14,33 @@ namespace Presence.Desktop.Views
{ {
public GroupView() public GroupView()
{ {
this.WhenActivated(disposables => { }); this.WhenActivated(action =>
{
action(ViewModel!.SelectFileInteraction.RegisterHandler(ShowFileDialog));
});
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
private async Task ShowFileDialog(IInteractionContext<string?, string?> context)
{
var topLevel = TopLevel.GetTopLevel(this);
var storageFile = await topLevel.StorageProvider.OpenFilePickerAsync(
new FilePickerOpenOptions()
{
AllowMultiple = false,
Title = context.Input
}
);
if (storageFile.Count > 0)
{
context.SetOutput(storageFile.First().Path.ToString());
}
else
{
// Обработка случая, когда выбор файла отменен
// Например, можно вывести сообщение или просто ничего не делать
}
}
} }
} }

View File

@ -2,7 +2,40 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:Presence.Desktop.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Presence.Desktop.Views.PresenceView"> x:Class="Presence.Desktop.Views.PresenceView"
Welcome to Avalonia! x:DataType="vm:PresenceViewModel">
<DockPanel Margin="10" Background="Aquamarine">
<StackPanel Orientation="Horizontal" Spacing="10" DockPanel.Dock="Top">
<!-- Выбор группы -->
<ComboBox ItemsSource="{Binding Groups}" SelectedItem="{Binding SelectedGroup}" Width="200" PlaceholderText="Выберите группу">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!-- Календарь -->
<Calendar SelectionMode="SingleRange" SelectedDatesChanged="DatesChanged"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="10">
<!-- Таблица с посещаемостью -->
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding AttendanceRecords}" CanUserSortColumns="True"
SelectionChanged="OnDataGridSelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Header="Дата" Binding="{Binding Date}"/>
<DataGridTextColumn Header="Номер урока" Binding="{Binding ClassNumber}" />
<DataGridTextColumn Header="ФИО" Binding="{Binding User.Name}" />
<DataGridCheckBoxColumn Header="Тип посещаемости" Binding="{Binding IsAttendence, Mode=TwoWay}" />
</DataGrid.Columns>
</DataGrid>
<Button Content="Удалить" Margin="0,10,0,0" Command="{Binding DeleteSelectedPresenceCommand}" />
</StackPanel>
</DockPanel>
</UserControl> </UserControl>

View File

@ -1,7 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using Presence.Desktop.Models;
using Presence.Desktop.ViewModels; using Presence.Desktop.ViewModels;
using ReactiveUI; using ReactiveUI;
@ -13,4 +17,35 @@ public partial class PresenceView : ReactiveUserControl<PresenceViewModel>
{ {
this.WhenActivated(disposables => { }); this.WhenActivated(disposables => { });
AvaloniaXamlLoader.Load(this); } AvaloniaXamlLoader.Load(this); }
private void OnDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (this.DataContext is PresenceViewModel viewModel)
{
// Обновляем выделенные элементы в ViewModel
viewModel.SelectedItems.Clear();
foreach (var item in e.AddedItems.OfType<PresencePresenter>())
{
viewModel.SelectedItems.Add(item);
}
}
}
private void DatesChanged(object sender, SelectionChangedEventArgs e)
{
Calendar cal = (Calendar)sender;
if (this.DataContext is PresenceViewModel viewModel)
{
if (viewModel.SelectedDate == null)
{
viewModel.SelectedDate = new List<DateTime?>();
}
viewModel.SelectedDate.Clear();
foreach (var date in cal.SelectedDates)
{
viewModel.SelectedDate.Add(date);
viewModel.FilterAttendanceRecords();
}
}
}
} }

View File

@ -9,6 +9,7 @@
"Presence.Desktop/1.0.0": { "Presence.Desktop/1.0.0": {
"dependencies": { "dependencies": {
"Avalonia": "11.2.1", "Avalonia": "11.2.1",
"Avalonia.Controls.DataGrid": "11.2.1",
"Avalonia.Desktop": "11.2.1", "Avalonia.Desktop": "11.2.1",
"Avalonia.Diagnostics": "11.2.1", "Avalonia.Diagnostics": "11.2.1",
"Avalonia.Fonts.Inter": "11.2.1", "Avalonia.Fonts.Inter": "11.2.1",

View File

@ -1 +1 @@
8ff83d2bcb3cec6472dc66a2a69c5cfafb8cbd5996d3bbe796f44278fe829520 56ae5ef5211e31f34c72fa8790282155735812ceabb8c9c1129ad7d327241a91

View File

@ -13,10 +13,10 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Presence.Desktop")] [assembly: System.Reflection.AssemblyCompanyAttribute("Presence.Desktop")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b8bf4628cce91d7266a54ce8ba848e91ee1b2569")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+ffb9d2134fbb1b7be6c05ec6ad7159dd069dd3fd")]
[assembly: System.Reflection.AssemblyProductAttribute("Presence.Desktop")] [assembly: System.Reflection.AssemblyProductAttribute("Presence.Desktop")]
[assembly: System.Reflection.AssemblyTitleAttribute("Presence.Desktop")] [assembly: System.Reflection.AssemblyTitleAttribute("Presence.Desktop")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class. // Создано классом WriteCodeFragment MSBuild.

View File

@ -1 +1 @@
4d609c065396d07151140e18cdb037e59080c5cb8458e11bf60ac5453325e867 68bd6e3390d8ca4bf09cdf5b154a30570d12f7994ca59f66302a0231ee630fcc

View File

@ -1 +1 @@
e68626bd1a98dbdea1f40f374f2417a325447b8270eac3ee295a31c6c470b799 0495b34aad8f14f248b68664d83675aa4c43aa8757ddb475b703d4e606ccfb0f

View File

@ -51,6 +51,10 @@
"target": "Package", "target": "Package",
"version": "[11.2.1, )" "version": "[11.2.1, )"
}, },
"Avalonia.Controls.DataGrid": {
"target": "Package",
"version": "[11.2.1, )"
},
"Avalonia.Desktop": { "Avalonia.Desktop": {
"target": "Package", "target": "Package",
"version": "[11.2.1, )" "version": "[11.2.1, )"

View File

@ -2473,6 +2473,7 @@
"projectFileDependencyGroups": { "projectFileDependencyGroups": {
"net8.0": [ "net8.0": [
"Avalonia >= 11.2.1", "Avalonia >= 11.2.1",
"Avalonia.Controls.DataGrid >= 11.2.1",
"Avalonia.Desktop >= 11.2.1", "Avalonia.Desktop >= 11.2.1",
"Avalonia.Diagnostics >= 11.2.1", "Avalonia.Diagnostics >= 11.2.1",
"Avalonia.Fonts.Inter >= 11.2.1", "Avalonia.Fonts.Inter >= 11.2.1",
@ -2531,6 +2532,10 @@
"target": "Package", "target": "Package",
"version": "[11.2.1, )" "version": "[11.2.1, )"
}, },
"Avalonia.Controls.DataGrid": {
"target": "Package",
"version": "[11.2.1, )"
},
"Avalonia.Desktop": { "Avalonia.Desktop": {
"target": "Package", "target": "Package",
"version": "[11.2.1, )" "version": "[11.2.1, )"

View File

@ -1,6 +1,6 @@
{ {
"version": 2, "version": 2,
"dgSpecHash": "yZq6gfkM/18=", "dgSpecHash": "bFYjHbhBv54=",
"success": true, "success": true,
"projectFilePath": "/home/gara/csharp/BIGPROGECT/presence/Presence.Desktop/Presence.Desktop.csproj", "projectFilePath": "/home/gara/csharp/BIGPROGECT/presence/Presence.Desktop/Presence.Desktop.csproj",
"expectedPackageFiles": [ "expectedPackageFiles": [

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("console_ui")] [assembly: System.Reflection.AssemblyCompanyAttribute("console_ui")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b8bf4628cce91d7266a54ce8ba848e91ee1b2569")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+ffb9d2134fbb1b7be6c05ec6ad7159dd069dd3fd")]
[assembly: System.Reflection.AssemblyProductAttribute("console_ui")] [assembly: System.Reflection.AssemblyProductAttribute("console_ui")]
[assembly: System.Reflection.AssemblyTitleAttribute("console_ui")] [assembly: System.Reflection.AssemblyTitleAttribute("console_ui")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
4bf58799393b54975cb249992c3335b53b5b1f8b9b387253b9f72465f1e756e4 43925848a55f2335dd5bf69a5a5a25d24ee5bbe218d379aff344f34875796193

View File

@ -17,6 +17,9 @@ namespace presence.data.Repository
bool DeletePresenceByGroup(int groupId); bool DeletePresenceByGroup(int groupId);
bool DeletePresenceByUser(int userId); bool DeletePresenceByUser(int userId);
bool DeletePresenceByDate(DateOnly startData, DateOnly endData); bool DeletePresenceByDate(DateOnly startData, DateOnly endData);
bool DeletePresenceByClassNumberAndDateAndUserId(int classNumber, DateOnly date, int userId);
void UpdateAttendance(PresenceDao presence);
} }

View File

@ -121,5 +121,28 @@ namespace presence.data.Repository
return false; return false;
} }
public bool DeletePresenceByClassNumberAndDateAndUserId(int classNumber, DateOnly date, int userId)
{
var PresenceToDelete = _remoteDatabaseContext.Presences.FirstOrDefault(x => x.Date == date && x.ClassNumber == classNumber && x.UserId == userId);
_remoteDatabaseContext.Presences.Remove(PresenceToDelete);
_remoteDatabaseContext.SaveChanges();
return true;
}
public void UpdateAttendance(PresenceDao presence)
{
if (presence == null) throw new ArgumentNullException(nameof(presence));
var nowPresence = _remoteDatabaseContext.Presences.FirstOrDefault(p => p.PresenceId == presence.PresenceId);
if (nowPresence == null)
throw new ArgumentNullException(nameof(presence));
nowPresence.IsAttendence = presence.IsAttendence;
_remoteDatabaseContext.SaveChanges();
}
} }
} }

Binary file not shown.

Binary file not shown.

View File

@ -13,10 +13,10 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("data")] [assembly: System.Reflection.AssemblyCompanyAttribute("data")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b8bf4628cce91d7266a54ce8ba848e91ee1b2569")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+ffb9d2134fbb1b7be6c05ec6ad7159dd069dd3fd")]
[assembly: System.Reflection.AssemblyProductAttribute("data")] [assembly: System.Reflection.AssemblyProductAttribute("data")]
[assembly: System.Reflection.AssemblyTitleAttribute("data")] [assembly: System.Reflection.AssemblyTitleAttribute("data")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class. // Создано классом WriteCodeFragment MSBuild.

View File

@ -1 +1 @@
a83c002440d4fc833844f0ad9fb2316eca5384ff634b577accf58e96b177ac86 cf96d5089cb6caf69b08d6f53371635a8397acc449b97042b83d1c21e6aa2e08

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
namespace presence.domain.Models namespace presence.domain.Models
{ {
public class Presence{ public class Presence{
public int Id { get; set;}
public required DateOnly Date {get; set;} public required DateOnly Date {get; set;}
public int ClassNumber {get; set;} public int ClassNumber {get; set;}
public bool IsAttendence {get; set;} public bool IsAttendence {get; set;}

View File

@ -16,17 +16,17 @@ namespace domain.Service
public class GroupService : IGroupUseCase public class GroupService : IGroupUseCase
{ {
private readonly IGroupRepository _groupRepository; private readonly IGroupRepository _groupRepository;
public GroupService(IGroupRepository groupRepository) private readonly IUserRepository _userRepository;
public GroupService(IGroupRepository groupRepository, IUserRepository userRepository)
{ {
_groupRepository = groupRepository; _groupRepository = groupRepository;
_userRepository = userRepository;
} }
public void AddGroup(AddGroupRequest addGroupRequest) public void AddGroup(AddGroupRequest addGroupRequest)
{ {
_groupRepository.AddGroup(new GroupDao { Name = addGroupRequest.Name }); _groupRepository.AddGroup(new GroupDao { Name = addGroupRequest.Name });
} }
public void AddGroupWithStudents(AddGroupWithStudentRequest addGroupWithStudents) public void AddGroupWithStudents(AddGroupWithStudentRequest addGroupWithStudents)
{ {
GroupDao groupDAO = new GroupDao { Name = addGroupWithStudents.addGroupRequest.Name }; GroupDao groupDAO = new GroupDao { Name = addGroupWithStudents.addGroupRequest.Name };
@ -80,5 +80,10 @@ namespace domain.Service
}).ToList() : new List<UserResponse>() }).ToList() : new List<UserResponse>()
}).ToList(); }).ToList();
} }
public void RemoveUserFromGroup(int UserId)
{
_userRepository.RemoveUserById(UserId);
}
} }
} }

View File

@ -14,6 +14,7 @@ namespace domain.UseCase
public IEnumerable<GroupResponse> GetGroupsWithStudents(); public IEnumerable<GroupResponse> GetGroupsWithStudents();
public void AddGroup(AddGroupRequest addGroupRequest); public void AddGroup(AddGroupRequest addGroupRequest);
public void AddGroupWithStudents(AddGroupWithStudentRequest addGroupWithStudents); public void AddGroupWithStudents(AddGroupWithStudentRequest addGroupWithStudents);
void RemoveUserFromGroup(int UserId);
} }
} }

View File

@ -229,5 +229,15 @@ namespace presence.domain.UseCase
{ {
return _presenceRepository.DeletePresenceByDate(startData, endData); return _presenceRepository.DeletePresenceByDate(startData, endData);
} }
public bool DeletePresenceByClassNumberAndDateAndUserId(int ClassNumber, DateOnly date, int userId)
{
return _presenceRepository.DeletePresenceByClassNumberAndDateAndUserId(ClassNumber, date, userId);
}
public void UpdateAttendance(PresenceDao presence)
{
_presenceRepository.UpdateAttendance(presence);
}
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -13,10 +13,10 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("domain")] [assembly: System.Reflection.AssemblyCompanyAttribute("domain")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b8bf4628cce91d7266a54ce8ba848e91ee1b2569")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+ffb9d2134fbb1b7be6c05ec6ad7159dd069dd3fd")]
[assembly: System.Reflection.AssemblyProductAttribute("domain")] [assembly: System.Reflection.AssemblyProductAttribute("domain")]
[assembly: System.Reflection.AssemblyTitleAttribute("domain")] [assembly: System.Reflection.AssemblyTitleAttribute("domain")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class. // Создано классом WriteCodeFragment MSBuild.

View File

@ -1 +1 @@
58b98f718e678f6a1418b7c4064bba479c5b66250df08cd49d82df8b5ba26dca c0e22eda5bbbbabacb18030d45375a59a2c3560af8350ea455c8ff608127f62e

Binary file not shown.

Binary file not shown.

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("presence_api")] [assembly: System.Reflection.AssemblyCompanyAttribute("presence_api")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b8bf4628cce91d7266a54ce8ba848e91ee1b2569")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+ffb9d2134fbb1b7be6c05ec6ad7159dd069dd3fd")]
[assembly: System.Reflection.AssemblyProductAttribute("presence_api")] [assembly: System.Reflection.AssemblyProductAttribute("presence_api")]
[assembly: System.Reflection.AssemblyTitleAttribute("presence_api")] [assembly: System.Reflection.AssemblyTitleAttribute("presence_api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
52221bf6c627d0a1f38ec9399dcd7b73938674fb1e29c05bd07d9c179faa01c4 34ef239cd86edabcf83988e2e31454a1505ecfa56a75ef26188aa31c45020f99

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("ui")] [assembly: System.Reflection.AssemblyCompanyAttribute("ui")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b8bf4628cce91d7266a54ce8ba848e91ee1b2569")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+ffb9d2134fbb1b7be6c05ec6ad7159dd069dd3fd")]
[assembly: System.Reflection.AssemblyProductAttribute("ui")] [assembly: System.Reflection.AssemblyProductAttribute("ui")]
[assembly: System.Reflection.AssemblyTitleAttribute("ui")] [assembly: System.Reflection.AssemblyTitleAttribute("ui")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
a566caacf63689b16cb3406c30a83366cd1327afd2187d25ebbffca47b491f0b 30af123abf1220bcb4b860b42e82b974f3441b16511baef32e539317699dd7a1