Compare commits

..

No commits in common. "35f253e7db2199cf2eb5503d4b8179ef82249bc2" and "39e7d5c4ee719da78a462fd45f7d346c98c75c42" have entirely different histories.

190 changed files with 1995 additions and 1502 deletions

View File

@ -1,9 +1,9 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35327.3
VisualStudioVersion = 17.11.35312.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "presence_new\Demo.csproj", "{31E5FFCB-821D-4C62-90AF-73CF0FED2F38}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "Demo\Demo.csproj", "{983820F6-FF31-4B3A-8593-831BC3904E80}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -11,15 +11,15 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{31E5FFCB-821D-4C62-90AF-73CF0FED2F38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31E5FFCB-821D-4C62-90AF-73CF0FED2F38}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31E5FFCB-821D-4C62-90AF-73CF0FED2F38}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31E5FFCB-821D-4C62-90AF-73CF0FED2F38}.Release|Any CPU.Build.0 = Release|Any CPU
{983820F6-FF31-4B3A-8593-831BC3904E80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{983820F6-FF31-4B3A-8593-831BC3904E80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{983820F6-FF31-4B3A-8593-831BC3904E80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{983820F6-FF31-4B3A-8593-831BC3904E80}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F3A9BD62-7626-4D6A-BEE1-35A21784C59F}
SolutionGuid = {4F43A963-447C-4FCB-BB78-8D315EC0F1D6}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,10 @@
using System;
namespace Demo.Data.Exceptions
{
public class UserNotFoundException : RepositoryException
{
public UserNotFoundException(Guid UserGuid)
: base($"Пользователь с ID {UserGuid} не найден.") { }
}
}

View File

@ -8,8 +8,10 @@ namespace Demo.domain.Models
{
public class GroupLocalEntity
{
public required int Id { get; set; }
public int Id { get; set; }
public required string Name { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.domain.Models
{
public class PresenceLocalEntity
{
public Guid UserGuid { get; set; }
public required int GroupId { get; set; }
public bool IsAttedance { get; set; } = true;
public required DateTime Date { get; set; }
public required int LessonNumber { get; set; }
}
}

View File

@ -14,7 +14,7 @@ namespace Demo.domain.Models
public required int GroupID { get; set; }
public bool Equals(UserLocalEnity? other)
{

View File

@ -17,7 +17,7 @@ namespace Demo.Data.LocalData
new GroupLocalEntity{ Id = 2, Name = "ИП1-22" },
new GroupLocalEntity{ Id = 3, Name = "ИП1-23" },
};
public static List<UserLocalEnity> users => new List<UserLocalEnity>
{
new UserLocalEnity{Guid=Guid.Parse("e6b9964d-ea9f-420a-84b9-af9633bbfab9"), FIO = "RandomFio", GroupID = 1 },
@ -30,7 +30,7 @@ namespace Demo.Data.LocalData
public static List<PresenceLocalEntity> presences => new List<PresenceLocalEntity>
{
};
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class Excel
public class AttendanceRecord
{
public Guid UserGuid { get; set; }
public string UserName { get; set; }
@ -16,4 +16,4 @@ namespace Demo.Data.RemoteData.RemoteDataBase.DAO
public int LessonNumber { get; set; }
public string GroupName { get; set; }
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using Demo.domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -9,7 +10,7 @@ namespace Demo.Data.RemoteData.RemoteDataBase.DAO
public class GroupDao
{
public int Id { get; set; }
public required string Name { get; set; }
public virtual IEnumerable<UserDao> Users { get; set; }
public string Name { get; set; }
public List<UserDao> Users { get; set; }
}
}

View File

@ -8,14 +8,11 @@ namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class PresenceDao
{
public int Id { get; set; }
public int PresenceId { get; set; }
public Guid UserGuid { get; set; }
public bool IsAttedance { get; set; } = true;
public DateOnly Date { get; set; }
public int LessonNumber { get; set; }
public virtual UserDao UserDao { get; set; }
public int GroupId { get; set; }
public int GroupId { get; set; }
}
}

View File

@ -8,11 +8,9 @@ namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class UserDao
{
public required string FIO { get; set; }
public Guid Guid { get; set; }
public required int GroupID { get; set; }
public GroupDao Group { get; set; }
public required string FIO { get; set; }
public required Guid UserGuid { get; set; }
public int GroupId { get; set; }
public GroupDao? Group { get; set; }
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class Temp
{
public Guid UserGuid;
public double ok;
public double skip;
}
}

View File

@ -0,0 +1,37 @@
using Microsoft.EntityFrameworkCore;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Demo.Data.RemoteData.RemoteDataBase
{
public class RemoteDatabaseContext: DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql("Host=45.67.56.214;Port=5421;Username=user15;Database=user15;Password=3XkvwMOb");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<GroupDao>().HasKey(group=>group.Id);
modelBuilder.Entity<GroupDao>().Property(group => group.Id).ValueGeneratedOnAdd();
modelBuilder.Entity<UserDao>().HasKey(user=>user.UserGuid);
modelBuilder.Entity<UserDao>().Property(user=>user.UserGuid).ValueGeneratedOnAdd();
modelBuilder.Entity<PresenceDao>().HasKey(presence =>presence.PresenceId);
modelBuilder.Entity<PresenceDao>().Property(presence=>presence.PresenceId).ValueGeneratedOnAdd();
}
public DbSet<GroupDao> Groups { get; set; }
public DbSet<UserDao> Users { get; set; }
public DbSet<PresenceDao> PresenceDaos { get; set; }
}
}

View File

@ -0,0 +1,75 @@
using Demo.Data.Exceptions;
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.Data.Repository;
using Demo.domain.Models;
using System.Collections.Generic;
using System.Linq;
public class GroupRepositoryImpl: IGroupRepository
{
private List<GroupLocalEntity> _groups = LocalStaticData.groups;
public GroupLocalEntity? GetGroupById(int groupId)
{
foreach (var group in _groups)
{
if (group.Id == groupId)
{
return group;
}
}
return null;
}
// Метод для получения всех групп
public List<GroupLocalEntity> GetAllGroups() => _groups;
// Метод для добавления новой группы
public void AddGroup(GroupLocalEntity group)
{
group.Id = _groups.Any() ? _groups.Max(g => g.Id) + 1 : 1;
_groups.Add(group);
}
// Метод для обновления существующей группы
public void UpdateGroupById(int groupId, GroupLocalEntity updatedGroup)
{
var existingGroup = GetGroupById(groupId);
if (existingGroup == null) throw new GroupNotFoundException(groupId);
}
public void RemoveGroupById(int groupId)
{
var existingGroup = GetGroupById(groupId);
if (existingGroup == null) throw new GroupNotFoundException(groupId);
if (_groups.Contains(existingGroup))
{
_groups.Remove(existingGroup);
}
}
List<GroupDao> IGroupRepository.GetAllGroups()
{
throw new NotImplementedException();
}
public bool UpdateGroupById(int groupID, GroupDao updatedGroup)
{
throw new NotImplementedException();
}
GroupDao IGroupRepository.GetGroupById(int groupID)
{
throw new NotImplementedException();
}
public bool AddGroup(string Name)
{
throw new NotImplementedException();
}
}

View File

@ -8,11 +8,11 @@ using System.Threading.Tasks;
namespace Demo.Data.Repository
{
public interface IUserRepository
public interface IGroupRepository
{
IEnumerable<UserLocalEnity> GetAllUsers { get; }
bool RemoveUserById(Guid userGuid);
UserLocalEnity? UpdateUser(UserLocalEnity user);
List<GroupDao> GetAllGroups();
bool UpdateGroupById(int groupID, GroupDao updatedGroup);
GroupDao GetGroupById(int groupID);
bool AddGroup(string Name);
}
}
}

View File

@ -0,0 +1,27 @@

using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using Demo.Domain.UseCase;
using Microsoft.EntityFrameworkCore.Metadata;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Data.Repository
{
public interface IPresenceRepository
{
List<PresenceDao> GetPresenceByDateAndGroup(DateTime date, int groupId);
void SavePresence(List<PresenceDao> presences);
List<PresenceDao> GetPresenceByGroup(int groupId);
DateOnly? GetLastDateByGroupId(int groupId);
List<PresenceDao> GetPresenceForAbsent(DateTime date, int GroupId);
void GetGeneralPresenceForGroup(int groupId);
void UpdateAtt(Guid UserGuid, int groupId, int firstLesson, int lastLesson, DateOnly date, bool isAttendance);
List<PresenceDao> GetAttendanceByGroup(int groupId);
}
}

View File

@ -0,0 +1,14 @@
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using System.Collections.Generic;
namespace Demo.Data.Repository
{
public interface IUserRepository
{
List<UserDao> GetAllUsers();
bool RemoveUserById(Guid UserGuid);
UserDao? UpdateUser(UserDao user);
List<UserDao> GetUserNames();
}
}

View File

@ -0,0 +1,53 @@
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo.Data.Repository
{
public class PresenceRepositoryImpl
{
private List<PresenceLocalEntity> _presences;
public PresenceRepositoryImpl()
{
_presences = new List<PresenceLocalEntity>(); // Ваши реальные данные
}
public void SavePresence(List<PresenceLocalEntity> presences)
{
foreach (var presence in presences)
{
var existingPresence = _presences.FirstOrDefault(p =>
p.Date == presence.Date &&
p.UserGuid == presence.UserGuid &&
p.LessonNumber == presence.LessonNumber);
if (existingPresence == null)
{
_presences.Add(presence);
}
else
{
existingPresence.IsAttedance = presence.IsAttedance;
}
}
}
public List<PresenceLocalEntity> GetPresenceByDateAndGroup(DateTime date, int groupId)
{
return _presences.Where(p => p.Date.Date == date.Date &&
LocalStaticData.users.Any(u => u.GroupID == groupId && u.Guid == p.UserGuid)).ToList();
}
public List<PresenceLocalEntity> GetPresenceByGroup(int groupId)
{
return _presences.Where(p => p.GroupId == groupId).ToList();
}
}
}

View File

@ -0,0 +1,122 @@
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Demo.Data.Repository
{
public class SQLGroupRepositoryImpl : IGroupRepository
{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLGroupRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext)
{
_remoteDatabaseContext = remoteDatabaseContext;
}
// Метод для добавления новой группы
public bool AddGroup(GroupDao newGroup)
{
var groupDao = new GroupDao
{
Name = newGroup.Name
};
_remoteDatabaseContext.Groups.Add(groupDao);
_remoteDatabaseContext.SaveChanges();
return true;
}
// Метод для получения группы по ID
public GroupDao GetGroupById(int groupId)
{
var groupDao = _remoteDatabaseContext.Groups
.Include(g => g.Users)
.FirstOrDefault(g => g.Id == groupId);
if (groupDao == null) return null;
return new GroupDao
{
Id = groupDao.Id,
Name = groupDao.Name,
Users = groupDao.Users.Select(u => new UserDao
{
UserGuid = u.UserGuid,
FIO = u.FIO,
GroupId = u.GroupId
}).ToList()
};
}
// Метод для получения всех групп
public List<GroupDao> GetAllGroups()
{
return _remoteDatabaseContext.Groups
.Include(g => g.Users)
.Select(g => new GroupDao
{
Id = g.Id,
Name = g.Name,
Users = g.Users.Select(u => new UserDao
{
UserGuid = u.UserGuid,
FIO = u.FIO,
GroupId = u.GroupId
}).ToList()
})
.ToList();
}
// Метод для обновления группы по ID
public bool UpdateGroupById(int groupId, GroupDao updatedGroup)
{
var groupDao = _remoteDatabaseContext.Groups
.Include(g => g.Users)
.FirstOrDefault(g => g.Id == groupId);
if (groupDao == null) return false;
groupDao.Name = updatedGroup.Name;
// Пример обновления списка пользователей
groupDao.Users = updatedGroup.Users.Select(user => new UserDao
{
UserGuid = user.UserGuid,
FIO = user.FIO,
GroupId = user.GroupId
}).ToList();
_remoteDatabaseContext.SaveChanges();
return true;
}
// Метод для удаления группы по ID
public bool RemoveGroupById(int groupId)
{
var groupDao = _remoteDatabaseContext.Groups.Find(groupId);
if (groupDao == null) return false;
_remoteDatabaseContext.Groups.Remove(groupDao);
_remoteDatabaseContext.SaveChanges();
return true;
}
public bool UpdateGroupById(int groupID, GroupLocalEntity updatedGroup)
{
throw new NotImplementedException();
}
public bool AddGroup(string Name)
{
var groupDao = new GroupDao
{
Name = Name
};
_remoteDatabaseContext.Groups.Add(groupDao);
_remoteDatabaseContext.SaveChanges();
return true;
}
}
}

View File

@ -0,0 +1,250 @@
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using DocumentFormat.OpenXml.InkML;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Demo.Data.Repository
{
public class SQLPresenceRepositoryImpl : IPresenceRepository
{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLPresenceRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext)
{
_remoteDatabaseContext = remoteDatabaseContext;
}
public List<PresenceDao> GetAttendanceByGroup(int groupId)
{
// Получаем записи посещаемости для указанной группы
return _remoteDatabaseContext.PresenceDaos
.Where(p => p.GroupId == groupId)
.Select(p => new PresenceDao
{
UserGuid = p.UserGuid,
GroupId = p.GroupId,
Date = p.Date,
LessonNumber = p.LessonNumber,
IsAttedance = p.IsAttedance
})
.ToList();
}
public List<PresenceDao> GetPresenceForAbsent(DateTime date, int GroupId)
{
return _remoteDatabaseContext.PresenceDaos.Where(p => p.GroupId == GroupId && p.Date == DateOnly.FromDateTime(date)).ToList();
}
public List<PresenceDao> GetPresenceByDateAndGroup(DateTime date, int groupId)
{
return _remoteDatabaseContext.PresenceDaos.Where(p => p.Date == DateOnly.FromDateTime(date) &&
_remoteDatabaseContext.Users.Any(u => u.GroupId == groupId && u.UserGuid == p.UserGuid)).ToList();
}
// Реализация метода для получения всех данных по группе
public List<PresenceDao> GetPresenceByGroup(int groupId)
{
return _remoteDatabaseContext.PresenceDaos.Where(p => p.GroupId == groupId)
.OrderBy(p => p.Date)
.ThenBy(p=>p.UserGuid).ToList();
}
public void SavePresence(List<PresenceDao> presences)
{
_remoteDatabaseContext.PresenceDaos.AddRange(presences.Select(it => new PresenceDao
{
Date = it.Date,
IsAttedance = it.IsAttedance,
LessonNumber = it.LessonNumber,
UserGuid = it.UserGuid,
GroupId = it.GroupId
}));
_remoteDatabaseContext.SaveChanges();
}
public void UpdateAtt(Guid UserGuid, int groupId, int firstLesson, int lastLesson, DateOnly date, bool isAttendance)
{
// Находим все записи по UserId, GroupId, LessonNumber (в диапазоне) и дате
var presences = _remoteDatabaseContext.PresenceDaos
.Where(p => p.UserGuid == UserGuid
&& p.GroupId == groupId
&& p.LessonNumber >= firstLesson
&& p.LessonNumber <= lastLesson
&& p.Date == date)
.ToList();
if (presences.Any())
{
// Обновляем значение IsAttendance для всех найденных записей
foreach (var presence in presences)
{
presence.IsAttedance = isAttendance;
}
_remoteDatabaseContext.SaveChanges(); // Сохраняем изменения в базе данных
Console.WriteLine($"Статус посещаемости для пользователя {UserGuid} с {firstLesson} по {lastLesson} урок обновлён.");
}
else
{
Console.WriteLine($"Посещаемость для пользователя ID: {UserGuid} на дату {date.ToShortDateString()} с {firstLesson} по {lastLesson} уроки не найдена.");
}
}
public DateOnly? GetLastDateByGroupId(int groupId)
{
// Проверяем наличие записей о посещаемости в базе данных для данной группы.
var lastDate = _remoteDatabaseContext.PresenceDaos
.Where(p => p.GroupId == groupId)
.OrderByDescending(p => p.Date)
.Select(p => p.Date)
.FirstOrDefault();
return lastDate == default ? (DateOnly?)null : lastDate;
}
public List<PresenceDao> PresenceSort(List<PresenceDao> presences)
{
presences=_remoteDatabaseContext.PresenceDaos.OrderBy(p=>p.Date).ToList();
return presences;
}
public void GetGeneralPresenceForGroup(int groupId)
{
var attendanceRecords = _remoteDatabaseContext.PresenceDaos
.Where(p => p.GroupId == groupId)
.OrderBy(p => p.LessonNumber)
.ToList();
var uniqueDates = _remoteDatabaseContext.PresenceDaos
.Select(p => p.Date)
.Distinct()
.ToList();
int sessionId = 0;
int lessonNum = 1;
double attendedSessions = 0;
int totalDays = -1;
int totalLessons = 0;
DateOnly currentDate = DateOnly.MinValue;
List<Guid> uniqueUserGuids = new List<Guid>();
foreach (var record in attendanceRecords)
{
if (!uniqueUserGuids.Contains(record.UserGuid))
{
uniqueUserGuids.Add(record.UserGuid);
}
if (record.Date != currentDate)
{
currentDate = record.Date;
sessionId++;
lessonNum = record.LessonNumber;
totalDays++;
}
if (record.LessonNumber != lessonNum && currentDate == record.Date)
{
lessonNum = record.LessonNumber;
totalLessons++;
sessionId++;
}
if (record.IsAttedance)
{
attendedSessions++;
}
}
Console.WriteLine(attendanceRecords.Count);
Console.WriteLine($"Количество студентов в группе: {uniqueUserGuids.Count}, " +
$"Количество проведённых занятий: {sessionId}, " +
$"Общий процент посещаемости группы: {attendedSessions / uniqueUserGuids.Count / lessonNum / uniqueDates.Count * 100}%");
List<AttendanceSummary> attendanceSummaryList = new List<AttendanceSummary>();
List<Guid> processedUserGuids = new List<Guid>();
double attendedCount = 0;
double missedCount = 0;
Guid currentUserGuid = Guid.Empty;
foreach (var userGuid in uniqueUserGuids)
{
var userAttendanceRecords = _remoteDatabaseContext.PresenceDaos
.Where(p => p.UserGuid == userGuid);
foreach (var record in userAttendanceRecords)
{
currentUserGuid = record.UserGuid;
if (!processedUserGuids.Contains(currentUserGuid))
{
missedCount = 0;
attendedCount = 0;
processedUserGuids.Add(currentUserGuid);
attendanceSummaryList.Add(new AttendanceSummary { UserGuid = currentUserGuid, Attended = attendedCount, Missed = missedCount });
if (record.IsAttedance)
{
attendanceSummaryList.First(a => a.UserGuid == currentUserGuid).Attended = attendedCount += 1;
}
else
{
attendanceSummaryList.First(a => a.UserGuid == currentUserGuid).Missed = missedCount += 1;
}
}
else
{
if (record.IsAttedance)
{
attendanceSummaryList.First(a => a.UserGuid == currentUserGuid).Attended = attendedCount += 1;
}
else
{
attendanceSummaryList.First(a => a.UserGuid == currentUserGuid).Missed = missedCount += 1;
}
}
}
}
foreach (var summary in attendanceSummaryList)
{
double attendancePercentage = summary.Attended / (summary.Missed + summary.Attended) * 100;
if (attendancePercentage < 40)
{
Console.ForegroundColor = ConsoleColor.Red;
}
Console.WriteLine($"ID Пользователя: {summary.UserGuid}, " +
$"Посетил: {summary.Attended}, " +
$"Пропустил: {summary.Missed}, " +
$"Процент посещаемости: {attendancePercentage}%");
Console.ForegroundColor = ConsoleColor.White;
}
}
public class AttendanceSummary
{
public Guid UserGuid { get; set; }
public double Attended { get; set; }
public double Missed { get; set; }
}
}
}

View File

@ -0,0 +1,61 @@
using Demo.Data.Exceptions;
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Demo.Data.Repository
{
public class SQLUserRepositoryImpl : IUserRepository
{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLUserRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext)
{
_remoteDatabaseContext = remoteDatabaseContext;
}
public bool RemoveUserById(Guid UserGuid)
{
var user = _remoteDatabaseContext.Users.FirstOrDefault(u => u.UserGuid == UserGuid);
if (user == null) throw new UserNotFoundException(UserGuid);
_remoteDatabaseContext.Users.Remove(user);
_remoteDatabaseContext.SaveChanges();
return true;
}
public UserDao? UpdateUser(UserDao user)
{
var existingUser = _remoteDatabaseContext.Users.FirstOrDefault(u => u.UserGuid == user.UserGuid);
if (existingUser == null) throw new UserNotFoundException(user.UserGuid);
// Обновляем поля существующего пользователя
existingUser.FIO = user.FIO;
existingUser.GroupId = user.GroupId;
_remoteDatabaseContext.SaveChanges();
return existingUser;
}
public List<UserDao> GetAllUsers()
{
// Возвращаем пользователей, отсортированных по UserId
return _remoteDatabaseContext.Users.OrderBy(u => u.UserGuid).ToList();
}
public List<UserDao> GetUserNames()
{
var users = GetAllUsers();
List<UserDao> names = new List<UserDao>();
foreach (var user in users)
{
names.Add(new UserDao{ UserGuid = user.UserGuid, FIO=user.FIO });
}
return names;
}
}
}

View File

@ -0,0 +1,37 @@
using Demo.Data.Exceptions;
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo.Data.Repository
{
public class UserRepositoryImpl
{
private List<UserLocalEnity> _users;
public UserRepositoryImpl()
{
_users = LocalStaticData.users;
}
public IEnumerable<UserLocalEnity> GetAllUsers => _users;
public bool RemoveUserById(Guid UserGuid)
{
var user = _users.FirstOrDefault(u => u.Guid == UserGuid);
if (user == null) throw new UserNotFoundException(UserGuid);
_users.Remove(user);
return true;
}
public UserDao? UpdateUser(UserDao user)
{
throw new NotImplementedException();
}
}
}

View File

@ -21,6 +21,7 @@
<ItemGroup>
<Folder Include="Data\RemoteData\RemoteApi\" />
<Folder Include="Migrations\" />
<Folder Include="Reports\" />
</ItemGroup>
</Project>

View File

@ -13,7 +13,6 @@ namespace Demo.domain.Models
public required int GroupId { get; set; }
public bool IsAttedance { get; set; } = true;
public required DateTime Date { get; set; }
public required int LessonNumber { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.Data.Repository;
using Demo.domain.Models;
@ -24,16 +25,16 @@ namespace Demo.Domain.UseCase
private void ValidateGroupId(int GroupId)
{
if (GroupId < 1)
if(GroupId < 1)
{
throw new ArgumentException("Введите корректный ID группы.");
}
}
// Приватный метод для валидации существования группы по ID
private GroupLocalEntity ValidateGroupExistence(int groupId)
private GroupDao ValidateGroupExistence(int groupId)
{
var existingGroup = _repositoryGroupImpl.GetAllGroup()
var existingGroup = _repositoryGroupImpl.GetAllGroups()
.FirstOrDefault(g => g.Id == groupId);
if (existingGroup == null)
@ -48,7 +49,7 @@ namespace Demo.Domain.UseCase
// Метод для получения списка всех групп
public List<Group> GetAllGroups()
{
return [.. _repositoryGroupImpl.GetAllGroup()
return [.. _repositoryGroupImpl.GetAllGroups()
.Select(it => new Group { Id = it.Id, Name = it.Name })];
}
@ -58,14 +59,14 @@ namespace Demo.Domain.UseCase
List<Group> GetAllGroups()
{
return [.. _repositoryGroupImpl
.GetAllGroup()
.GetAllGroups()
.Select(
it => new Group
it => new Group
{ Id = it.Id, Name = it.Name }
)
];
}
foreach (var group in GetAllGroups())
foreach(var group in GetAllGroups())
{
if (IdGroup == group.Id)
{
@ -73,44 +74,21 @@ namespace Demo.Domain.UseCase
}
}
}
// Метод для добавления новой группы
public void AddGroup(string groupName)
{
ValidateGroupName(groupName);
ValidateGroupName(groupName);
var newId = _repositoryGroupImpl.GetAllGroup().Any()
? _repositoryGroupImpl.GetAllGroup().Max(g => g.Id) + 1
: 1;
GroupLocalEntity newGroup = new GroupLocalEntity
{
Id = newId,
Name = groupName
};
_repositoryGroupImpl.AddGroup(newGroup);
}
public void RemoveGroupById(int groupId)
{
ValidateGroupId(groupId);
var existingGroup = ValidateGroupExistence(groupId);
List<Group> _groups = GetAllGroups();
// Находим группу по ID и удаляем ее
var groupToRemove = _groups.FirstOrDefault(g => g.Id == existingGroup.Id);
if (groupToRemove != null)
{
_groups.Remove(groupToRemove);
_repositoryGroupImpl.RemoveGroupById(existingGroup.Id);
}
else
{
throw new ArgumentException("Группа не найдена.");
// Обработка случая, если группа не найдена (например, выброс исключения)
}
_repositoryGroupImpl.AddGroup(newGroup.Name);
}
@ -121,9 +99,7 @@ namespace Demo.Domain.UseCase
var existingGroup = ValidateGroupExistence(groupId);
existingGroup.Name = newGroupName;
_repositoryGroupImpl.UpdateGroupById(existingGroup.Id, existingGroup);
_repositoryGroupImpl.UpdateGroupById(groupId,existingGroup);
}
}
}

View File

@ -0,0 +1,210 @@
using ClosedXML.Excel;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.Data.Repository;
using Demo.domain.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Domain.UseCase
{
public class UseCaseGeneratePresence
{
public readonly IUserRepository _userRepository;
public readonly IPresenceRepository _presenceRepository;
private readonly IGroupRepository _groupRepository;
public UseCaseGeneratePresence(IUserRepository userRepository, IPresenceRepository presenceRepository, IGroupRepository groupRepository)
{
_userRepository = userRepository;
_presenceRepository = presenceRepository;
_groupRepository = groupRepository;
}
public Dictionary<string, List<AttendanceRecord>> GetAllAttendanceByGroups()
{
var attendanceByGroup = new Dictionary<string, List<AttendanceRecord>>();
var allGroups = _groupRepository.GetAllGroups();
foreach (var group in allGroups)
{
var groupAttendance = _presenceRepository.GetAttendanceByGroup(group.Id);
var attendanceRecords = new List<AttendanceRecord>();
foreach (var record in groupAttendance)
{
var names = _userRepository.GetUserNames().Where(u => u.UserGuid == record.UserGuid);
foreach (var name in names)
{
attendanceRecords.Add(new AttendanceRecord
{
UserName = name.FIO,
UserGuid = name.UserGuid,
Date = record.Date,
IsAttedance = record.IsAttedance,
LessonNumber = record.LessonNumber,
GroupName = group.Name
});
}
}
attendanceByGroup.Add(group.Name, attendanceRecords);
}
return attendanceByGroup;
}
public void ExportAttendanceToExcel()
{
var attendanceByGroup = GetAllAttendanceByGroups();
string projectDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName;
string reportsFolderPath = Path.Combine(projectDirectory, "Reports");
string filePath = Path.Combine(reportsFolderPath, "AttendanceReport.xlsx");
// Создаем папку, если она не существует
if (!Directory.Exists(reportsFolderPath))
{
Directory.CreateDirectory(reportsFolderPath);
}
using (var workbook = new XLWorkbook())
{
foreach (var group in attendanceByGroup)
{
var worksheet = workbook.Worksheets.Add($"{group.Key}");
worksheet.Cell(1, 1).Value = "ФИО";
worksheet.Cell(1, 2).Value = "Группа";
worksheet.Cell(1, 3).Value = "Дата";
worksheet.Cell(1, 4).Value = "Занятие";
worksheet.Cell(1, 5).Value = "Статус";
int row = 2;
int lesNum = 1;
foreach (var record in group.Value.OrderBy(r => r.Date).ThenBy(r => r.LessonNumber).ThenBy(r => r.UserGuid))
{
if (lesNum != record.LessonNumber)
{
row++;
}
worksheet.Cell(row, 1).Value = record.UserName;
worksheet.Cell(row, 2).Value = record.GroupName;
worksheet.Cell(row, 3).Value = record.Date.ToString("dd.MM.yyyy");
worksheet.Cell(row, 4).Value = record.LessonNumber;
worksheet.Cell(row, 5).Value = record.IsAttedance ? "Присутствует" : "Отсутствует";
row++;
lesNum = record.LessonNumber;
}
worksheet.Columns().AdjustToContents();
}
workbook.SaveAs(filePath);
}
}
public List<PresenceDao> GetPresenceByDateAndGroup(DateTime date, int groupId)
{
return _presenceRepository.GetPresenceByDateAndGroup(date, groupId);
}
public void GeneratePresenceDaily(int firstLesson, int lastLesson, int groupId)
{
try
{
var users = _userRepository.GetAllUsers().Where(u => u.GroupId == groupId).ToList();
// Находим последнюю дату посещаемости для данной группы
DateOnly startDate = _presenceRepository.GetLastDateByGroupId(groupId)?.AddDays(1)
?? DateOnly.FromDateTime(DateTime.Today);
List<PresenceDao> presences = new List<PresenceDao>();
for (int lessonNumber = firstLesson; lessonNumber <= lastLesson; lessonNumber++)
{
foreach (var user in users)
{
var presence = new PresenceDao
{
UserGuid = user.UserGuid,
GroupId = user.GroupId,
Date = startDate,
LessonNumber = lessonNumber,
IsAttedance = true
};
try
{
_presenceRepository.SavePresence(new List<PresenceDao> { presence });
Console.WriteLine($"Посещаемость добавлена для UserId = {user.UserGuid}, LessonNumber = {lessonNumber} на дату {startDate}");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при добавлении посещаемости для UserId = {user.UserGuid}: {ex.Message}");
if (ex.InnerException != null)
{
Console.WriteLine($"Inner exception: {ex.InnerException.Message}");
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при генерации посещаемости: {ex.Message}");
if (ex.InnerException != null)
{
Console.WriteLine($"Inner exception: {ex.InnerException.Message}");
}
}
}
public void GenerateWeeklyPresence(int firstLesson, int lastLesson, int groupId, DateTime startTime)
{
for (int i = 0; i < 7; i++)
{
DateTime currentTime = startTime.AddDays(i);
GeneratePresenceDaily(firstLesson, lastLesson, groupId);
}
}
// Отметить пользователя как отсутствующего на диапазоне занятий
public void MarkUserAbsentForLessons(Guid UserGuid, int groupId, int firstLesson, int lastLesson, DateTime date)
{
List<PresenceDao> presences = _presenceRepository.GetPresenceForAbsent(date, groupId);
// Обновляем состояние присутствия для указанных занятий
foreach (var presence in presences.Where(p => p.UserGuid == UserGuid && p.LessonNumber >= firstLesson && p.LessonNumber <= lastLesson))
{
presence.IsAttedance = false; // Устанавливаем отсутствие
Console.WriteLine($"PresenceId: {presence.PresenceId}, UserId: {presence.UserGuid}, Lesson Num: {presence.LessonNumber}, Att: {presence.IsAttedance}");
}
// Сохраняем изменения в репозитории
_presenceRepository.UpdateAtt(UserGuid, groupId, firstLesson, lastLesson, DateOnly.FromDateTime(date), false);
}
public List<PresenceDao> GetAllPresenceByGroup(int groupId)
{
return _presenceRepository.GetPresenceByGroup(groupId);
}
public void GetGeneralPresence(int groupId)
{
_presenceRepository.GetGeneralPresenceForGroup(groupId);
}
}
}

View File

@ -1,4 +1,6 @@
using Demo.Data.Exceptions;
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.Data.Repository;
using Demo.domain.Models;
@ -8,11 +10,12 @@ namespace Demo.Domain.UseCase
{
private readonly IUserRepository _repositoryUserImpl;
private readonly IGroupRepository _repositoryGroupImpl;
public UserUseCase(IUserRepository repositoryImpl, IGroupRepository repositoryGroupImpl)
private readonly IPresenceRepository _repositoryPresenceImpl;
public UserUseCase(IUserRepository repositoryImpl, IGroupRepository repositoryGroupImpl, IPresenceRepository presenceRepository)
{
_repositoryUserImpl = repositoryImpl;
_repositoryGroupImpl = repositoryGroupImpl;
_repositoryPresenceImpl = presenceRepository;
}
// Приватный метод для валидации ФИО пользователя
@ -24,12 +27,22 @@ namespace Demo.Domain.UseCase
}
}
// Приватный метод для валидации существования пользователя по ID
private UserLocalEnity ValidateUserExistence(Guid userGuid)
public void RemovePresenceByUserId(Guid UserGuid)
{
var user = _repositoryUserImpl.GetAllUsers
.FirstOrDefault(u => u.Guid == userGuid);
using (var context = new RemoteDatabaseContext())
{
var presences = context.PresenceDaos.Where(p => p.UserGuid == UserGuid).ToList();
context.PresenceDaos.RemoveRange(presences);
context.SaveChanges();
}
}
// Приватный метод для валидации существования пользователя по ID
private UserDao ValidateUserExistence(Guid UserGuid)
{
var user = _repositoryUserImpl.GetAllUsers()
.FirstOrDefault(u => u.UserGuid == UserGuid);
if (user == null)
{
throw new Exception("Пользователь не найден.");
@ -39,9 +52,9 @@ namespace Demo.Domain.UseCase
}
// Приватный метод для валидации существования группы по ID
private GroupLocalEntity ValidateGroupExistence(int groupId)
private GroupDao ValidateGroupExistence(int groupId)
{
var group = _repositoryGroupImpl.GetAllGroup()
var group = _repositoryGroupImpl.GetAllGroups()
.FirstOrDefault(g => g.Id == groupId);
if (group == null)
@ -53,24 +66,24 @@ namespace Demo.Domain.UseCase
}
// Вывести всех пользователей
public List<User> GetAllUsers() => _repositoryUserImpl.GetAllUsers
.Join(_repositoryGroupImpl.GetAllGroup(),
user => user.GroupID,
group => group.Id,
(user, group) =>
public List<User> GetAllUsers() => _repositoryUserImpl.GetAllUsers()
.Join(_repositoryGroupImpl.GetAllGroups(),
user => user.GroupId, // Ключ для пользователей
group => group.Id, // Ключ для групп
(user, group) => // Результирующий объект
new User
{
Guid = user.UserGuid,
FIO = user.FIO,
Guid = user.Guid,
Group = new Group { Id = group.Id, Name = group.Name }
}).ToList();
// Удалить пользователя по id
public bool RemoveUserById(Guid userGuid)
public bool RemoveUserById(Guid UserGuid)
{
try
{
return _repositoryUserImpl.RemoveUserById(userGuid);
return _repositoryUserImpl.RemoveUserById(UserGuid);
}
catch (UserNotFoundException ex)
{
@ -84,51 +97,48 @@ namespace Demo.Domain.UseCase
}
}
// Обновить пользователя по guid
public User UpdateUser(User user)
// Обновить пользователя по id
public UserDao UpdateUser(UserDao user)
{
ValidateUserFIO(user.FIO);
ValidateGroupExistence(user.Group.Id);
ValidateGroupExistence(user.GroupId);
UserLocalEnity userLocalEnity = new UserLocalEnity
UserDao userDao = new UserDao
{
UserGuid = user.UserGuid,
FIO = user.FIO,
GroupID = user.Group.Id,
Guid = user.Guid
GroupId = user.GroupId
};
UserLocalEnity? result = _repositoryUserImpl.UpdateUser(userLocalEnity);
UserDao? result = _repositoryUserImpl.UpdateUser(userDao);
if (result == null)
{
throw new Exception("Ошибка при обновлении пользователя.");
}
var groupEntity = ValidateGroupExistence(result.GroupID);
var groupEntity = ValidateGroupExistence(result.GroupId);
return new User
return new UserDao
{
UserGuid =user.UserGuid,
FIO = result.FIO,
Guid = result.Guid,
Group = new Group
{
Id = groupEntity.Id,
Name = groupEntity.Name
}
GroupId = result.GroupId
};
}
// Найти пользователя по id
public User FindUserById(Guid userGuid)
public UserDao FindUserById(Guid UserGuid)
{
var user = ValidateUserExistence(userGuid);
var group = ValidateGroupExistence(user.GroupID);
var user = ValidateUserExistence(UserGuid);
var group = ValidateGroupExistence(user.GroupId);
return new User
return new UserDao
{
UserGuid = user.UserGuid,
FIO = user.FIO,
Guid = user.Guid,
Group = new Group { Id = group.Id, Name = group.Name }
Group = new GroupDao { Id = group.Id, Name=group.Name }
};
}
}

View File

@ -12,8 +12,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Demo.Migrations
{
[DbContext(typeof(RemoteDatabaseContext))]
[Migration("20241104183721_createbase")]
partial class createbase
[Migration("20241104200529_db")]
partial class db
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -44,29 +44,35 @@ namespace Demo.Migrations
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
{
b.Property<Guid>("UserGuid")
.HasColumnType("uuid");
b.Property<int>("PresenceId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("PresenceId"));
b.Property<DateOnly>("Date")
.HasColumnType("date");
b.Property<int>("GroupId")
.HasColumnType("integer");
b.Property<bool>("IsAttedance")
.HasColumnType("boolean");
b.Property<int>("LessonNumber")
.HasColumnType("integer");
b.Property<int>("GroupId")
.HasColumnType("integer");
b.Property<Guid>("UserGuid")
.HasColumnType("uuid");
b.HasKey("UserGuid", "Date", "IsAttedance", "LessonNumber");
b.HasKey("PresenceId");
b.ToTable("PresenceDaos");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
{
b.Property<Guid>("Guid")
b.Property<Guid>("UserGuid")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
@ -74,32 +80,21 @@ namespace Demo.Migrations
.IsRequired()
.HasColumnType("text");
b.Property<int>("GroupID")
b.Property<int>("GroupId")
.HasColumnType("integer");
b.HasKey("Guid");
b.HasKey("UserGuid");
b.HasIndex("GroupID");
b.HasIndex("GroupId");
b.ToTable("Users");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
{
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", "UserDao")
.WithMany()
.HasForeignKey("UserGuid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("UserDao");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
{
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", "Group")
.WithMany("Users")
.HasForeignKey("GroupID")
.HasForeignKey("GroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();

View File

@ -7,7 +7,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Demo.Migrations
{
/// <inheritdoc />
public partial class createbase : Migration
public partial class db : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
@ -25,30 +25,12 @@ namespace Demo.Migrations
table.PrimaryKey("PK_Groups", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Guid = table.Column<Guid>(type: "uuid", nullable: false),
FIO = table.Column<string>(type: "text", nullable: false),
GroupID = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Guid);
table.ForeignKey(
name: "FK_Users_Groups_GroupID",
column: x => x.GroupID,
principalTable: "Groups",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "PresenceDaos",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false).Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
PresenceId = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
UserGuid = table.Column<Guid>(type: "uuid", nullable: false),
IsAttedance = table.Column<bool>(type: "boolean", nullable: false),
Date = table.Column<DateOnly>(type: "date", nullable: false),
@ -57,13 +39,32 @@ namespace Demo.Migrations
},
constraints: table =>
{
table.PrimaryKey("PK_PresenceDaos", x => x.Id );
table.PrimaryKey("PK_PresenceDaos", x => x.PresenceId);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
UserGuid = table.Column<Guid>(type: "uuid", nullable: false),
FIO = table.Column<string>(type: "text", nullable: false),
GroupId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.UserGuid);
table.ForeignKey(
name: "FK_Users_Groups_GroupId",
column: x => x.GroupId,
principalTable: "Groups",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Users_GroupID",
name: "IX_Users_GroupId",
table: "Users",
column: "GroupID");
column: "GroupId");
}
/// <inheritdoc />

View File

@ -41,31 +41,35 @@ namespace Demo.Migrations
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
{
b.Property<int>("Id")
.HasColumnType ("integer");
b.Property<Guid>("UserGuid")
.HasColumnType("uuid");
b.Property<int>("PresenceId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("PresenceId"));
b.Property<DateOnly>("Date")
.HasColumnType("date");
b.Property<int>("GroupId")
.HasColumnType("integer");
b.Property<bool>("IsAttedance")
.HasColumnType("boolean");
b.Property<int>("LessonNumber")
.HasColumnType("integer");
b.Property<int>("GroupId")
.HasColumnType("integer");
b.Property<Guid>("UserGuid")
.HasColumnType("uuid");
b.HasKey("PresenceId");
b.HasKey("Id");
b.ToTable("PresenceDaos");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
{
b.Property<Guid>("Guid")
b.Property<Guid>("UserGuid")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
@ -73,32 +77,21 @@ namespace Demo.Migrations
.IsRequired()
.HasColumnType("text");
b.Property<int>("GroupID")
b.Property<int>("GroupId")
.HasColumnType("integer");
b.HasKey("Guid");
b.HasKey("UserGuid");
b.HasIndex("GroupID");
b.HasIndex("GroupId");
b.ToTable("Users");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
{
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", "UserDao")
.WithMany()
.HasForeignKey("UserGuid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("UserDao");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
{
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", "Group")
.WithMany("Users")
.HasForeignKey("GroupID")
.HasForeignKey("GroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();

View File

@ -16,10 +16,7 @@ services
.AddSingleton<UserUseCase>()
.AddSingleton<GroupUseCase>()
.AddSingleton<UseCaseGeneratePresence>()
.AddSingleton<GroupConsoleUI>()
.AddSingleton<PresenceConsole>()
.AddSingleton<MainMenuUI>();
@ -28,4 +25,4 @@ var serviceProvider = services.BuildServiceProvider();
MainMenuUI mainMenuUI = serviceProvider.GetService<MainMenuUI>();
// Выводим главное меню
mainMenuUI.DisplayMenu();
mainMenuUI.DisplayMenu();

View File

@ -47,13 +47,6 @@ namespace Demo.UI
}
}
public void RemoveGroup(string groupIdStr)
{
int groupId = int.Parse(groupIdStr);
_groupUseCase.RemoveGroupById(groupId);
Console.WriteLine($"Группа с ID: {groupId} удалена");
}
// Метод для обновления названия группы
public void UpdateGroupName(int groupId, string newGroupName)
{

View File

@ -1,6 +1,7 @@
using Demo.domain.Models;
using Demo.Domain.UseCase;
using System;
using System.Globalization;
namespace Demo.UI
{
@ -14,58 +15,57 @@ namespace Demo.UI
{
_userConsoleUI = new UserConsoleUI(userUseCase);
_groupConsoleUI = new GroupConsoleUI(groupUseCase);
_presenceConsoleUI = new PresenceConsole(presenceUseCase); // Передаем GroupAttendanceService
_presenceConsoleUI = new PresenceConsole(presenceUseCase);
}
public void DisplayMenu()
{
while (true)
{
Console.WriteLine("\n==================== Главная Панель ====================\n");
Console.WriteLine("\n=-= Главное меню =-=\n");
Console.WriteLine("~~~~~~~~~~~~~~~ УПРАВЛЕНИЕ ПОЛЬЗОВАТЕЛЯМИ ~~~~~~~~~~~~~~~");
Console.WriteLine("1. Показать список всех пользователей");
Console.WriteLine("2. Удалить пользователя по его ID");
Console.WriteLine("3. Обновить данные пользователя по ID");
Console.WriteLine("4. Найти пользователя по его ID");
Console.WriteLine("=-= Команды с Пользователями =-=");
Console.WriteLine("1. Вывести всех пользователей");
Console.WriteLine("2. Удалить пользователя по id");
Console.WriteLine("3. Обновить пользователя по id");
Console.WriteLine("4. Найти пользователя по id");
Console.WriteLine();
Console.WriteLine("~~~~~~~~~~~~~~~ УПРАВЛЕНИЕ ГРУППАМИ ~~~~~~~~~~~~~~~");
Console.WriteLine("5. Показать список всех групп");
Console.WriteLine("6. Создать новую группу");
Console.WriteLine("7. Удалить группу по ID");
Console.WriteLine("8. Изменить название существующей группы");
Console.WriteLine("9. Найти группу по ее ID");
Console.WriteLine("=-= Команды с Группами =-=");
Console.WriteLine("5. Вывести все группы");
Console.WriteLine("6. Добавить группу");
Console.WriteLine("7. Изменить название группы");
Console.WriteLine("8. Поиск группы по ID");
Console.WriteLine();
Console.WriteLine("=-= Команды Presence =-=");
Console.WriteLine("9. Сгенерировать посещаемость на день");
Console.WriteLine("10. Сгенерировать посещаемость на неделю");
Console.WriteLine("11. Показать посещаемость");
Console.WriteLine("12. Отметить пользователя как отсутствующего");
Console.WriteLine("13. Вывести всю посещаемость группы");
Console.WriteLine("14. Вывести общую информацию об посещаемости по группе");
Console.WriteLine("15. Вывести отчётв Excel");
Console.WriteLine();
Console.WriteLine("0. Выход");
Console.Write("\nВаш выбор: ");
string comand = Console.ReadLine();
Console.WriteLine();
Console.WriteLine("~~~~~~~~~~~~~~~ УПРАВЛЕНИЕ ПОСЕЩАЕМОСТЬЮ ~~~~~~~~~~~~~~~");
Console.WriteLine("10. Сгенерировать посещаемость на текущий день");
Console.WriteLine("11. Сгенерировать посещаемость на текущую неделю");
Console.WriteLine("12. Показать посещаемость всех пользователей");
Console.WriteLine("13. Отметить пользователя как отсутствующего");
Console.WriteLine("14. Вывести посещаемость группы по ID");
Console.WriteLine("15. Показать информацию о посещаемости группы");
Console.WriteLine();
Console.WriteLine("========================================================");
Console.WriteLine("0. Выход из программы");
Console.Write("\nВыберите команду: ");
string command = Console.ReadLine();
Console.WriteLine();
switch (command)
switch (comand)
{
case "1":
// Отображение всех пользователей
_userConsoleUI.DisplayAllUsers();
break;
case "2":
// Удаление пользователя по ID
Console.Write("Введите ID пользователя для удаления: ");
if (Guid.TryParse(Console.ReadLine(), out Guid userGuid))
string inputGuid = Console.ReadLine();
if (Guid.TryParse(inputGuid, out Guid UserGuid))
{
_userConsoleUI.RemoveUserById(userGuid);
_userConsoleUI.RemoveUserById(UserGuid);
}
else
{
@ -74,8 +74,10 @@ namespace Demo.UI
break;
case "3":
// Обновление пользователя по ID
Console.Write("Введите ID пользователя для обновления: ");
if (Guid.TryParse(Console.ReadLine(), out Guid updateUserGuid))
string updateGuidInput = Console.ReadLine();
if (Guid.TryParse(updateGuidInput, out Guid updateUserGuid))
{
_userConsoleUI.UpdateUserById(updateUserGuid);
}
@ -86,8 +88,10 @@ namespace Demo.UI
break;
case "4":
// Поиск пользователя по ID
Console.Write("Введите ID пользователя для поиска: ");
if (Guid.TryParse(Console.ReadLine(), out Guid findUserGuid))
string findGuidInput = Console.ReadLine();
if (Guid.TryParse(findGuidInput, out Guid findUserGuid))
{
_userConsoleUI.FindUserById(findUserGuid);
}
@ -98,21 +102,25 @@ namespace Demo.UI
break;
case "5":
// Отображение всех групп
_groupConsoleUI.DisplayAllGroups();
break;
case "6":
// Добавление новой группы
Console.Write("Введите название новой группы: ");
string newGroupName = Console.ReadLine();
_groupConsoleUI.AddGroup(newGroupName);
break;
case "7":
Console.Write("Введите ID группы для удаления: ");
string groupIdForDeleteStr = Console.ReadLine(); // Считываем ID как строку
if (!string.IsNullOrWhiteSpace(groupIdForDeleteStr) && int.TryParse(groupIdForDeleteStr, out int groupIdForDelete)) // Проверяем, что строка не пустая и может быть преобразована в int
// Изменение названия группы
Console.Write("Введите ID группы для изменения: ");
if (int.TryParse(Console.ReadLine(), out int groupId))
{
_groupConsoleUI.RemoveGroup(groupIdForDeleteStr); // Передаем строку в метод
Console.Write("Введите новое название группы: ");
string newName = Console.ReadLine();
_groupConsoleUI.UpdateGroupName(groupId, newName);
}
else
{
@ -121,32 +129,16 @@ namespace Demo.UI
break;
case "8":
Console.Write("Введите ID группы для изменения: ");
if (int.TryParse(Console.ReadLine(), out int groupIdToUpdate))
// Поиск группы
Console.Write("Введите ID группы для поиска : ");
if (int.TryParse(Console.ReadLine(), out int IdGroup))
{
Console.Write("Введите новое название группы: ");
string newName = Console.ReadLine();
_groupConsoleUI.UpdateGroupName(groupIdToUpdate, newName);
}
else
{
Console.WriteLine("Неверный формат ID группы");
_groupConsoleUI.FindGroupById(IdGroup);
}
break;
case "9":
Console.Write("Введите ID группы для поиска: ");
if (int.TryParse(Console.ReadLine(), out int idGroupToFind))
{
_groupConsoleUI.FindGroupById(idGroupToFind);
}
else
{
Console.WriteLine("Неверный формат ID группы");
}
break;
case "10":
// Генерация посещаемости на день
Console.Write("Введите номер первого занятия: ");
int firstLesson = int.Parse(Console.ReadLine());
Console.Write("Введите номер последнего занятия: ");
@ -158,7 +150,8 @@ namespace Demo.UI
Console.WriteLine("Посещаемость на день сгенерирована.");
break;
case "11":
case "10":
// Генерация посещаемости на неделю
Console.Write("Введите номер первого занятия: ");
int firstLessonForWeek = int.Parse(Console.ReadLine());
Console.Write("Введите номер последнего занятия: ");
@ -170,7 +163,8 @@ namespace Demo.UI
Console.WriteLine("Посещаемость на неделю сгенерирована.");
break;
case "12":
case "11":
// Отображение посещаемости
Console.Write("Введите дату (гггг-мм-дд): ");
DateTime date = DateTime.Parse(Console.ReadLine());
Console.Write("Введите ID группы: ");
@ -179,9 +173,10 @@ namespace Demo.UI
_presenceConsoleUI.DisplayPresence(date, groupForPresenceView);
break;
case "13":
case "12":
// Отметить пользователя как отсутствующего
Console.Write("Введите ID пользователя: ");
userGuid = Guid.Parse(Console.ReadLine());
UserGuid = Guid.Parse(Console.ReadLine());
Console.Write("Введите номер первого занятия: ");
int firstAbsLesson = int.Parse(Console.ReadLine());
Console.Write("Введите номер последнего занятия: ");
@ -189,28 +184,32 @@ namespace Demo.UI
Console.Write("Введите ID группы: ");
int absGroupId = int.Parse(Console.ReadLine());
_presenceConsoleUI.MarkUserAsAbsent(DateTime.Now, absGroupId, userGuid, firstAbsLesson, lastAbsLesson);
Console.Write("Введите дату (дд.мм.гггг): ");
string dateInput = Console.ReadLine();
DateTime absenceDate;
if (!DateTime.TryParseExact(dateInput, "d.M.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out absenceDate))
{
Console.WriteLine("Ошибка: Введен некорректный формат даты. Пожалуйста, используйте формат дд.мм.гггг.");
return; // Завершает выполнение, если дата некорректна
}
_presenceConsoleUI.MarkUserAbsent(absenceDate, absGroupId, UserGuid, firstAbsLesson, lastAbsLesson);
Console.WriteLine("Пользователь отмечен как отсутствующий.");
break;
case "14":
case "13":
Console.Write("Введите ID группы: ");
int groupIdForAllPresence = int.Parse(Console.ReadLine());
_presenceConsoleUI.DisplayAllPresenceByGroup(groupIdForAllPresence);
break;
case "15":
Console.Write("Введите ID группы для отображения информации о посещаемости: ");
if (int.TryParse(Console.ReadLine(), out int groupIdForAttendanceInfo))
{
}
else
{
Console.WriteLine("Неверный формат ID группы");
}
case "14":
Console.Write("Введите ID группы: ");
int searchGroupId= int.Parse(Console.ReadLine());
_presenceConsoleUI.DisplayGeneralPresence(searchGroupId);
break;
case "15":
_presenceConsoleUI.ExportAttendanceToExcel();
break;
case "0":
Console.WriteLine("Выход...");
return;
@ -223,4 +222,4 @@ namespace Demo.UI
}
}
}
}
}

166
Demo/UI/PresenceConsole.cs Normal file
View File

@ -0,0 +1,166 @@
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using Demo.Domain.UseCase;
using System;
using System.Collections.Generic;
namespace Demo.UI
{
public class PresenceConsole
{
private readonly UseCaseGeneratePresence _presenceUseCase;
public PresenceConsole(UseCaseGeneratePresence presenceUseCase)
{
_presenceUseCase = presenceUseCase;
}
public void ExportAttendanceToExcel()
{
try
{
_presenceUseCase.ExportAttendanceToExcel();
Console.WriteLine("Данные посещаемости успешно экспортированы в Excel.");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при экспорте посещаемости: {ex.Message}");
}
}
// Метод для генерации посещаемости на день
public void GeneratePresenceForDay(DateTime date, int groupId, int firstLesson, int lastLesson)
{
try
{
_presenceUseCase.GeneratePresenceDaily(firstLesson, lastLesson, groupId);
Console.WriteLine("Посещаемость на день успешно сгенерирована.");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при генерации посещаемости: {ex.Message}");
}
}
// Метод для генерации посещаемости на неделю
public void GeneratePresenceForWeek(DateTime date, int groupId, int firstLesson, int lastLesson)
{
try
{
_presenceUseCase.GenerateWeeklyPresence(firstLesson, lastLesson, groupId, date);
Console.WriteLine("Посещаемость на неделю успешно сгенерирована.");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при генерации посещаемости: {ex.Message}");
}
}
// Метод для отображения посещаемости на конкретную дату и группу
public void DisplayPresence(DateTime date, int groupId)
{
try
{
List<PresenceDao> presences = _presenceUseCase.GetPresenceByDateAndGroup(date, groupId);
if (presences == null || presences.Count == 0)
{
Console.WriteLine("Посещаемость на выбранную дату отсутствует.");
return;
}
// Сортируем присутствия по номеру занятия и ID пользователя
var sortedPresences = presences.OrderBy(p => p.LessonNumber)
.ThenBy(p => p.UserGuid);
Console.WriteLine($"\nПосещаемость на {date.ToShortDateString()} для группы с ID {groupId}:");
Console.WriteLine("---------------------------------------------");
int previousLessonNumber = -1; // Инициализация для сравнения
foreach (var presence in sortedPresences)
{
if (previousLessonNumber != presence.LessonNumber)
{
Console.WriteLine("---------------------------------------------");
previousLessonNumber = presence.LessonNumber;
}
string status = presence.IsAttedance ? "Присутствует" : "Отсутствует";
Console.WriteLine($"Пользователь ID: {presence.UserGuid}, Занятие {presence.LessonNumber}: {status}");
}
Console.WriteLine("---------------------------------------------");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при выводе посещаемости: {ex.Message}");
}
}
public void MarkUserAbsent(DateTime date, int groupId, Guid UserGuid, int firstLesson, int lastLesson)
{
_presenceUseCase.MarkUserAbsentForLessons(UserGuid, groupId, firstLesson, lastLesson, date);
}
public void DisplayGeneralPresence(int groupId)
{
_presenceUseCase.GetGeneralPresence(groupId);
}
public void DisplayAllPresenceByGroup(int groupId)
{
try
{
// Получаем все посещения для группы
var presences = _presenceUseCase.GetAllPresenceByGroup(groupId);
if (presences == null || presences.Count == 0)
{
Console.WriteLine($"Посещаемость для группы с ID {groupId} отсутствует.");
return;
}
// Группируем по дате
var groupedPresences = presences.GroupBy(p => p.Date);
foreach (var group in groupedPresences)
{
Console.WriteLine("===================================================");
Console.WriteLine($"Дата: {group.Key.ToString("dd.MM.yyyy")}");
Console.WriteLine("===================================================");
// Группируем по занятию
var groupedByLesson = group.GroupBy(p => p.LessonNumber);
foreach (var lessonGroup in groupedByLesson)
{
Console.WriteLine($"Занятие {lessonGroup.Key}:");
// Создаем HashSet для уникальных пользователей
var UserGuid = new HashSet<Guid>();
foreach (var presence in lessonGroup)
{
// Проверяем, добавляется ли пользователь в HashSet
if (UserGuid.Add(presence.UserGuid))
{
string status = presence.IsAttedance ? "Присутствует" : "Отсутствует";
Console.WriteLine($"Пользователь ID: {presence.UserGuid}, Статус: {status}");
}
}
Console.WriteLine("---------------------------------------------------");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при выводе посещаемости: {ex.Message}");
}
}
}
}

View File

@ -1,4 +1,6 @@
using Demo.Domain.UseCase;
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.Repository;
using Demo.Domain.UseCase;
using System;
using System.Text;
@ -29,24 +31,32 @@ namespace Demo.UI
}
// Метод для удаления пользователя по ID
public void RemoveUserById(Guid userGuid)
public void RemoveUserById(Guid UserGuid)
{
string output = _userUseCase.RemoveUserById(userGuid) ? "Пользователь удален" : "Пользователь не найден";
// Сначала удаляем все записи о присутствии пользователя
_userUseCase.RemovePresenceByUserId(UserGuid);
// Теперь удаляем пользователя
string output = _userUseCase.RemoveUserById(UserGuid) ? "Пользователь удален" : "Пользователь не найден";
Console.WriteLine($"\n{output}\n");
}
// Метод для обновления пользователя по ID
public void UpdateUserById(Guid userGuid)
public void UpdateUserById(Guid UserGuid)
{
try
{
var user = _userUseCase.FindUserById(userGuid);
var user = _userUseCase.FindUserById(UserGuid);
Console.WriteLine($"Текущие данные: {user.FIO}, {user.Group.Name}");
Console.WriteLine($"Текущие данные: {user.FIO}");
Console.Write("\nВведите новое ФИО: ");
string newFIO = Console.ReadLine();
Console.Write("\nВведите новый ID группы (или оставьте такой же): ");
int GroupId = int.Parse(Console.ReadLine());
user.FIO = newFIO;
user.GroupId = GroupId;
_userUseCase.UpdateUser(user);
Console.WriteLine("\nПользователь обновлен.\n");
@ -58,12 +68,12 @@ namespace Demo.UI
}
// Метод для поиска пользователя по ID
public void FindUserById(Guid userGuid)
public void FindUserById(Guid UserGuid)
{
var user = _userUseCase.FindUserById(userGuid);
var user = _userUseCase.FindUserById(UserGuid);
if (user != null)
{
Console.WriteLine($"\nПользователь найден: {user.Guid}, {user.FIO}, {user.Group.Name}\n");
Console.WriteLine($"\nПользователь найден: {user.UserGuid}, {user.FIO}, {user.Group.Name}\n");
}
else
{

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More