first (projects)

This commit is contained in:
1billy17 2024-11-01 22:07:13 +03:00
commit 28d492421b
40 changed files with 2039 additions and 0 deletions

363
.gitignore vendored Normal file
View File

@ -0,0 +1,363 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd

View File

@ -0,0 +1,118 @@
// <auto-generated />
using System;
using Demo.Data.RemoteData.RemoteDataBase;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Demo.Migrations
{
[DbContext(typeof(RemoteDatabaseContext))]
[Migration("20241028031712_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDAO", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("ID");
b.ToTable("Groups");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDAO", b =>
{
b.Property<Guid>("UserGuid")
.HasColumnType("uuid");
b.Property<DateOnly>("Date")
.HasColumnType("date");
b.Property<int>("LessonNumber")
.HasColumnType("integer");
b.Property<bool>("IsAttedance")
.HasColumnType("boolean");
b.Property<Guid>("userDAOGuid")
.HasColumnType("uuid");
b.HasKey("UserGuid", "Date", "LessonNumber");
b.HasIndex("userDAOGuid");
b.ToTable("PresenceDaos");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDAO", b =>
{
b.Property<Guid>("Guid")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<int>("GroupID")
.HasColumnType("integer");
b.HasKey("Guid");
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("userDAOGuid")
.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")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Group");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDAO", b =>
{
b.Navigation("Users");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,92 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Demo.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Groups",
columns: table => new
{
ID = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
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
{
UserGuid = table.Column<Guid>(type: "uuid", nullable: false),
Date = table.Column<DateOnly>(type: "date", nullable: false),
LessonNumber = table.Column<int>(type: "integer", nullable: false),
IsAttedance = table.Column<bool>(type: "boolean", nullable: false),
userDAOGuid = table.Column<Guid>(type: "uuid", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PresenceDaos", x => new { x.UserGuid, x.Date, x.LessonNumber });
table.ForeignKey(
name: "FK_PresenceDaos_Users_userDAOGuid",
column: x => x.userDAOGuid,
principalTable: "Users",
principalColumn: "Guid",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_PresenceDaos_userDAOGuid",
table: "PresenceDaos",
column: "userDAOGuid");
migrationBuilder.CreateIndex(
name: "IX_Users_GroupID",
table: "Users",
column: "GroupID");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "PresenceDaos");
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "Groups");
}
}
}

View File

@ -0,0 +1,115 @@
// <auto-generated />
using System;
using Demo.Data.RemoteData.RemoteDataBase;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Demo.Migrations
{
[DbContext(typeof(RemoteDatabaseContext))]
partial class RemoteDatabaseContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDAO", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ID"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("ID");
b.ToTable("Groups");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDAO", b =>
{
b.Property<Guid>("UserGuid")
.HasColumnType("uuid");
b.Property<DateOnly>("Date")
.HasColumnType("date");
b.Property<int>("LessonNumber")
.HasColumnType("integer");
b.Property<bool>("IsAttedance")
.HasColumnType("boolean");
b.Property<Guid>("userDAOGuid")
.HasColumnType("uuid");
b.HasKey("UserGuid", "Date", "LessonNumber");
b.HasIndex("userDAOGuid");
b.ToTable("PresenceDaos");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDAO", b =>
{
b.Property<Guid>("Guid")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<int>("GroupID")
.HasColumnType("integer");
b.HasKey("Guid");
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("userDAOGuid")
.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")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Group");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDAO", b =>
{
b.Navigation("Users");
});
#pragma warning restore 612, 618
}
}
}

26
console_ui/Program.cs Normal file
View File

@ -0,0 +1,26 @@
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.Repository;
using Demo.Domain.UseCase;
using Demo.UI;
using Microsoft.Extensions.DependencyInjection;
IServiceCollection services = new ServiceCollection();
services
.AddDbContext<RemoteDatabaseContext>()
.AddSingleton<IGroupRepository, SQLGroupRepositoryImpl>()
.AddSingleton<IUserRepository, SQLUserRepositoryImpl>()
.AddSingleton<IPresenceRepository, SQLPresenceRepositoryImpl>()
.AddSingleton<IAdminRepository, SQLAdminRepositoryImpl>()
.AddSingleton<IGroupUseCase, GroupUseCase>()
.AddSingleton<IUserUseCase, UserUseCase>()
.AddSingleton<IPresenceUseCase, PresenceUseCase>()
.AddSingleton<IAdminUseCase, AdminUseCase>()
.AddSingleton<UserConsoleUI>()
.AddSingleton<AdminConsoleUI>()
.AddSingleton<MainMenuUI>();
var serviceProvider = services.BuildServiceProvider();
MainMenuUI? mainMenuUI = serviceProvider.GetService<MainMenuUI>();

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\domain\domain.csproj" />
<ProjectReference Include="..\data\data.csproj" />
<ProjectReference Include="..\ui\ui.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

8
data/Entity/Group.cs Normal file
View File

@ -0,0 +1,8 @@
namespace Demo.Domain.Models
{
public class GroupLocalEntity
{
public required int ID {get; set; }
public required string Name{get; set; }
}
}

9
data/Entity/Presence.cs Normal file
View File

@ -0,0 +1,9 @@
namespace Demo.Domain.Models{
public class PresenceLocalEntity{
public required Guid UserGuid{get; set; }
public bool IsAttedance { get; set; } = true;
public required DateOnly Date { get; set; }
public required int LessonNumber { get; set; }
}
}

13
data/Entity/User.cs Normal file
View File

@ -0,0 +1,13 @@
namespace Demo.Domain.Models{
public class UserLocalEntity :IEquatable<UserLocalEntity>{
public required string FIO{get; set; }
public Guid Guid {get; set; }
public required int GroupID{get; set; }
public bool Equals(UserLocalEntity? other)
{
if (other == null) return false;
return this.Guid.Equals(other.Guid);
}
}
}

View File

@ -0,0 +1,24 @@
using Demo.Domain.Models;
namespace Demo.Data.LocalData
{
public class LocalStaticData
{
public static List<GroupLocalEntity> groups => new List<GroupLocalEntity>
{
new GroupLocalEntity{ID = 1, Name = "ИП1-21"},
new GroupLocalEntity{ID = 2, Name = "ИП1-22"},
new GroupLocalEntity{ID = 3, Name = "ИП1-23"},
};
public static List<UserLocalEntity> users => new List<UserLocalEntity>
{
new UserLocalEntity{Guid=Guid.Parse("e6b9964d-ea9f-420a-84b9-af9633bbfab9"), FIO = "RandomFio", GroupID = 1 },
new UserLocalEntity{Guid=Guid.Parse("8388d931-5bef-41be-a152-78f1aca980ed"), FIO = "RandomFio1", GroupID = 2 },
new UserLocalEntity{Guid=Guid.Parse("ed174548-49ed-4503-a902-c970cbf27173"), FIO = "RandomFio2", GroupID = 3 },
new UserLocalEntity{Guid=Guid.Parse("614c0a23-5bd5-43ae-b48e-d5750afbc282"), FIO = "RandomFio3", GroupID = 1 },
new UserLocalEntity{Guid=Guid.Parse("efcc1473-c116-4244-b3f7-f2341a5c3003"), FIO = "RandomFio4", GroupID = 2 },
new UserLocalEntity{Guid=Guid.Parse("60640fb3-ace2-4cad-81d5-a0a58bc2dbbd"), FIO = "RandomFio5", GroupID = 3 },
};
}
}

View File

@ -0,0 +1,9 @@
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class GroupDAO
{
public int ID {get; set; }
public string Name{get; set; }
public IEnumerable<UserDAO> Users {get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class PresenceDAO
{
public Guid UserGuid {get; set; }
public bool IsAttedance {get; set; }
public DateOnly Date {get; set; }
public int LessonNumber {get; set; }
public UserDAO userDAO {get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System.Text.RegularExpressions;
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class UserDAO
{
public string FIO { get; set; }
public Guid Guid {get; set; }
public int GroupID {get; set;}
public GroupDAO Group {get; set; }
}
}

View File

@ -0,0 +1,30 @@
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Microsoft.EntityFrameworkCore;
namespace Demo.Data.RemoteData.RemoteDataBase
{
public class RemoteDatabaseContext: DbContext
{
public DbSet<GroupDAO> Groups {get; set; }
public DbSet<UserDAO> Users {get; set;}
public DbSet<PresenceDAO> PresenceDaos{get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql("Host=localhost;Port=5433;Username=myuser;Password=mypassword;Database=mydatabase");
}
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.Guid);
modelBuilder.Entity<UserDAO>().Property(user => user.Guid).ValueGeneratedOnAdd();
modelBuilder.Entity<PresenceDAO>().HasKey(presence => new {
presence.UserGuid,
presence.Date,
presence.LessonNumber
});
}
}
}

View File

@ -0,0 +1,17 @@
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Domain.Models;
namespace Demo.Data.Repository
{
public class SQLAdminRepositoryImpl : IAdminRepository{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLAdminRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext){
_remoteDatabaseContext = remoteDatabaseContext;
}
public List<GroupLocalEntity> GetAllGroup()
{
return _remoteDatabaseContext.Groups.Select(x => new GroupLocalEntity{Name = x.Name, ID = x.ID}).ToList();
}
}
}

View File

@ -0,0 +1,55 @@
using Demo.Domain.Models;
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
namespace Demo.Data.Repository
{
public class SQLGroupRepositoryImpl : IGroupRepository
{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLGroupRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext){
_remoteDatabaseContext = remoteDatabaseContext;
GetAllGroups = _remoteDatabaseContext.Groups.Select(x => new GroupLocalEntity{Name = x.Name, ID = x.ID}).ToList();
}
public List<GroupLocalEntity> GetAllGroups
{ get; set; }
public List<GroupLocalEntity> GetAllGroup()
{
return _remoteDatabaseContext.Groups.Select(x => new GroupLocalEntity{Name = x.Name, ID = x.ID}).ToList();
}
public GroupLocalEntity? GetGroupById(int ID){
var groupDAO = _remoteDatabaseContext.Groups.FirstOrDefault(x => x.ID == ID);
return new GroupLocalEntity{Name = groupDAO.Name, ID = groupDAO.ID};
}
public GroupLocalEntity? CreateGroup(string Name) {
GroupDAO groupDAO = new GroupDAO{Name = Name};
var result = _remoteDatabaseContext.Groups.Add(groupDAO);
_remoteDatabaseContext.SaveChanges();
return new GroupLocalEntity{Name = groupDAO.Name, ID = groupDAO.ID};
}
public GroupLocalEntity? UpdateGroup(GroupLocalEntity updatedGroup){
var group = _remoteDatabaseContext.Groups.FirstOrDefault(x => x.ID == updatedGroup.ID);
if (group == null){
return null;
}
group.Name = updatedGroup.Name;
_remoteDatabaseContext.SaveChanges();
return new GroupLocalEntity{Name = group.Name, ID = group.ID};
}
public bool RemoveGroupByID(int ID){
var groupDAO = _remoteDatabaseContext.Groups.FirstOrDefault(x => x.ID == ID);
_remoteDatabaseContext.Groups.Remove(groupDAO);
_remoteDatabaseContext.SaveChanges();
return true;
}
}
}

View File

@ -0,0 +1,9 @@
using Demo.Domain.Models;
namespace Demo.Data.Repository
{
public interface IAdminRepository
{
List<GroupLocalEntity> GetAllGroup();
}
}

View File

@ -0,0 +1,13 @@
using Demo.Domain.Models;
namespace Demo.Data.Repository
{
public interface IGroupRepository
{
List<GroupLocalEntity> GetAllGroup();
GroupLocalEntity? GetGroupById(int ID);
bool RemoveGroupByID(int groupId);
GroupLocalEntity? UpdateGroup(GroupLocalEntity updatedGroup);
GroupLocalEntity? CreateGroup(string Name);
}
}

View File

@ -0,0 +1,11 @@
using Demo.Domain.Models;
namespace Demo.Data.Repository
{
public interface IPresenceRepository
{
List<PresenceLocalEntity> GetAllPresences();
void IsAttedance(int firstLesson, int lastLesson, DateOnly date, Guid UserGuid);
List<PresenceLocalEntity> GeneratePresence(List<PresenceLocalEntity> presenceLocalEntities);
}
}

View File

@ -0,0 +1,13 @@
using Demo.Domain.Models;
namespace Demo.Data.Repository
{
public interface IUserRepository
{
List<UserLocalEntity> GetAllUser();
UserLocalEntity? GetUserByGuid(Guid guid);
List<UserLocalEntity> GetUsersByGroupID(int groupID);
bool RemoveUserByGuid(Guid guid);
UserLocalEntity? UpdateUser(UserLocalEntity updatedUser);
}
}

View File

@ -0,0 +1,55 @@
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.Domain.Models;
namespace Demo.Data.Repository
{
public class SQLPresenceRepositoryImpl : IPresenceRepository
{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLPresenceRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext){
_remoteDatabaseContext = remoteDatabaseContext;
GetAllPresence = _remoteDatabaseContext.PresenceDaos.Select(x => new PresenceLocalEntity{UserGuid = x.UserGuid, Date = x.Date, LessonNumber = x.LessonNumber, IsAttedance = x.IsAttedance}).ToList();
}
public List<PresenceLocalEntity> GetAllPresence = new List<PresenceLocalEntity>{};
public List<PresenceLocalEntity> GetAllPresences(){
return _remoteDatabaseContext.PresenceDaos.Select(x => new PresenceLocalEntity{UserGuid = x.UserGuid, Date = x.Date, LessonNumber = x.LessonNumber, IsAttedance = x.IsAttedance}).ToList();
}
public List<PresenceLocalEntity> GeneratePresence(List<PresenceLocalEntity> presenceLocalEntities)
{
var presences = presenceLocalEntities.Select(x => new PresenceDAO
{
UserGuid = x.UserGuid,
IsAttedance = x.IsAttedance,
LessonNumber = x.LessonNumber,
Date = x.Date,
userDAO = _remoteDatabaseContext.Users.FirstOrDefault(u => u.Guid == x.UserGuid)
}).ToList();
_remoteDatabaseContext.PresenceDaos.AddRange(presences);
_remoteDatabaseContext.SaveChanges();
return presenceLocalEntities;
}
public void IsAttedance(int firstLesson, int lastLesson, DateOnly date, Guid UserGuid){
var presencesToUpdate = _remoteDatabaseContext.PresenceDaos
.Where(x => x.LessonNumber >= firstLesson
&& x.LessonNumber <= lastLesson
&& x.Date == date
&& x.UserGuid == UserGuid)
.ToList();
foreach(var presence in presencesToUpdate){
presence.IsAttedance = false;
}
_remoteDatabaseContext.SaveChanges();
}
}
}

View File

@ -0,0 +1,60 @@
using Demo.Domain.Models;
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase;
namespace Demo.Data.Repository
{
public class SQLUserRepositoryImpl : IUserRepository
{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLUserRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext){
_remoteDatabaseContext = remoteDatabaseContext;
GetAllUsers = _remoteDatabaseContext.Users.Select(x => new UserLocalEntity{FIO = x.FIO, Guid = x.Guid, GroupID = x.GroupID}).ToList();
}
public List<UserLocalEntity> GetAllUsers
{ get; set; }
public List<UserLocalEntity> GetAllUser(){
return _remoteDatabaseContext.Users.Select(x => new UserLocalEntity{FIO = x.FIO, Guid = x.Guid, GroupID = x.GroupID}).ToList();
}
public UserLocalEntity? GetUserByGuid(Guid guid){
var userDAO = _remoteDatabaseContext.Users.FirstOrDefault(x => x.Guid == guid);
return new UserLocalEntity{FIO = userDAO.FIO, GroupID = userDAO.GroupID, Guid = guid};
}
public List<UserLocalEntity> GetUsersByGroupID(int groupID)
{
return _remoteDatabaseContext.Users
.Where(x => x.GroupID == groupID)
.Select(x => new UserLocalEntity
{
FIO = x.FIO,
Guid = x.Guid,
GroupID = x.GroupID
})
.ToList();
}
public bool RemoveUserByGuid(Guid guid){
var userDAO = _remoteDatabaseContext.Users.FirstOrDefault(x => x.Guid == guid);
_remoteDatabaseContext.Users.Remove(userDAO);
_remoteDatabaseContext.SaveChanges();
return true;
}
public UserLocalEntity? UpdateUser(UserLocalEntity updatedUser){
var user = _remoteDatabaseContext.Users.FirstOrDefault(x => x.Guid == updatedUser.Guid);
if (user == null){
return null;
}
user.FIO = updatedUser.FIO;
user.GroupID = updatedUser.GroupID;
_remoteDatabaseContext.SaveChanges();
return new UserLocalEntity{FIO = user.FIO, Guid = user.Guid, GroupID = user.GroupID};
}
}
}

18
data/data.csproj Normal file
View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
</ItemGroup>
</Project>

13
domain/Models/Group.cs Normal file
View File

@ -0,0 +1,13 @@
namespace Demo.Domain.Models
{
public class Group
{
public required int ID{get; set; }
public required string Name{get; set; }
public static Group Parse(string input){
string[] words = input.Split(" ");
return new Group{ID = Convert.ToInt32(words[0]), Name = words[1]};
}
}
}

11
domain/Models/Presence.cs Normal file
View File

@ -0,0 +1,11 @@
namespace Demo.Domain.Models
{
public class Presence
{
public required User User{get; set; }
public bool IsAttedance { get; set; } = true;
public required DateOnly Date { get; set; }
public required int LessonNumber { get; set; }
}
}

38
domain/Models/User.cs Normal file
View File

@ -0,0 +1,38 @@
namespace Demo.Domain.Models
{
public class User
{
public required string FIO{get; set; }
public Guid Guid{get; set; }
public required Group Group{get; set; }
public static User Parse(string input)
{
string[] words = input.Split(" ");
if (words.Length < 4)
{
throw new FormatException("Input string does not have the expected number of elements.");
}
try
{
return new User
{
FIO = words[0],
Guid = Guid.Parse(words[1]),
Group = new Group
{
ID = Convert.ToInt32(words[2]),
Name = words[3]
}
};
}
catch (FormatException ex)
{
Console.WriteLine("Error parsing input: " + ex.Message);
throw;
}
}
}
}

View File

@ -0,0 +1,123 @@
using ClosedXML.Excel;
using Demo.Data.Repository;
using Demo.Domain.Models;
using DocumentFormat.OpenXml.Office.Word;
using DocumentFormat.OpenXml.Wordprocessing;
namespace Demo.Domain.UseCase
{
public class AdminUseCase : IAdminUseCase
{
private readonly IAdminRepository _repositoryAdminImpl;
private readonly IUserRepository _repositoryUserImpl;
private readonly IPresenceRepository _repositoryPresenceImpl;
public AdminUseCase(IAdminRepository repositoryAdminImpl, IUserRepository repositoryUserImpl, IPresenceRepository repositoryPresenceImpl)
{
_repositoryAdminImpl = repositoryAdminImpl;
_repositoryUserImpl = repositoryUserImpl;
_repositoryPresenceImpl = repositoryPresenceImpl;
}
public bool ExcelExport(int groupID){
var users = _repositoryUserImpl.GetUsersByGroupID(groupID);
var groupPresences = GetPresenceByGroup(groupID);
var dates = new List<DateOnly>();
foreach(var presence in groupPresences){
if (!dates.Contains(presence.Date)){
dates.Add(presence.Date);
}
}
using (var workbook = new XLWorkbook()){
var worksheet = workbook.Worksheets.Add(groupID);
worksheet.Cell(1, 1).Value = "FIO";
worksheet.Range(1, 1, 2, 1).Merge();
var colIndex = 2;
foreach (var date in dates) {
worksheet.Cell(1, colIndex).Value = date.ToString("dd.MM.yy");
worksheet.Range(1, colIndex, 1, colIndex + 8).Merge();
colIndex += 9;
}
var k = 2;
foreach(var date in dates){
for (int lesson = 1; lesson <= 9; lesson++){
worksheet.Cell(2, k).Value = lesson;
k++;
}
}
var lessonColIndex = 2;
var rowIndex = 3;
foreach(var user in users){
worksheet.Cell(rowIndex, 1).Value = user.FIO;
var userPresences = GetPresenceByUser(user.Guid);
foreach(var date in dates){
for (int lesson = 1; lesson <= 9; lesson++){
var presence = userPresences.FirstOrDefault(p => p.Date == date && p.LessonNumber == lesson);
if (presence != null){
worksheet.Cell(rowIndex, lessonColIndex).Value = presence.IsAttedance ? "Истина" : "Ложь";
} else{
worksheet.Cell(rowIndex, lessonColIndex).Value = "-";
}
lessonColIndex++;
}
}
rowIndex++;
lessonColIndex = 2;
}
workbook.SaveAs($"gruop_{groupID}.xlsx");
}
return true;
}
public List<Presence> GetPresenceByUser(Guid userGuid){
var user = _repositoryUserImpl.GetUserByGuid(userGuid);
var presenceByUser = _repositoryPresenceImpl.GetAllPresences()
.Where(user => userGuid == user.UserGuid)
.Select(presence => new Presence{
User = new User{
Guid = user.Guid,
Group = new Group{
ID = user.GroupID,
Name = _repositoryAdminImpl.GetAllGroup().First(group => group.ID == user.GroupID).Name
},
FIO = user.FIO
},
LessonNumber = presence.LessonNumber,
Date = presence.Date,
IsAttedance = presence.IsAttedance
}).ToList();
return presenceByUser;
}
public List<Presence> GetPresenceByGroup(int groupID){
var usersByGroup = _repositoryUserImpl.GetAllUser()
.Where(user => user.GroupID == groupID).ToList();
var presenceByGroup = _repositoryPresenceImpl.GetAllPresences()
.Where(x => usersByGroup.Any(user => user.Guid == x.UserGuid))
.Select(presence => new Presence{
User = new User{
Guid = presence.UserGuid,
Group = new Group{
ID = groupID,
Name = _repositoryAdminImpl.GetAllGroup().First(group => group.ID == groupID).Name
},
FIO = usersByGroup.First(user => user.Guid == presence.UserGuid).FIO,
},
LessonNumber = presence.LessonNumber,
Date = presence.Date,
IsAttedance = presence.IsAttedance
}).ToList();
return presenceByGroup;
}
}
}

View File

@ -0,0 +1,54 @@
using Demo.Domain.Models;
using Demo.Data.Repository;
namespace Demo.Domain.UseCase
{
public class GroupUseCase : IGroupUseCase
{
private readonly IUserRepository _repositoryUserImpl;
private readonly IGroupRepository _repositoryGroupImpl;
public GroupUseCase(IGroupRepository repositoryGroupImpl, IUserRepository repositoryUserImpl)
{
_repositoryGroupImpl = repositoryGroupImpl;
_repositoryUserImpl = repositoryUserImpl;
}
public List<Group> GetAllGroups() => _repositoryGroupImpl.GetAllGroup()
.Select(it => new Group{ID = it.ID, Name = it.Name}).ToList();
public Group GetGroupById(int groupID)
{
GroupLocalEntity? groupLocalEntity = _repositoryGroupImpl.GetGroupById(groupID);
if (groupLocalEntity == null) throw new Exception("bello");
return new Group{ID = groupID, Name = groupLocalEntity.Name};
}
public bool CreateGroup(string Name){
_repositoryGroupImpl.CreateGroup(Name);
return true;
}
public Group UpdateGroup(Group group)
{
GroupLocalEntity groupLocalEntity = new GroupLocalEntity
{
ID = group.ID,
Name = group.Name
};
GroupLocalEntity? result = _repositoryGroupImpl.UpdateGroup(groupLocalEntity);
if (result == null)
{
throw new Exception("Не удалось обновить пользователя: пользователь не найден.");
}
return new Group
{
ID = result.ID,
Name = result.Name
};
}
public bool RemoveGroupByID(int userID) {
return _repositoryGroupImpl.RemoveGroupByID(userID);
}
}
}

View File

@ -0,0 +1,10 @@
using Demo.Domain.Models;
namespace Demo.Domain.UseCase
{
public interface IAdminUseCase{
bool ExcelExport(int groupID);
List<Presence> GetPresenceByUser(Guid userGuid);
List<Presence> GetPresenceByGroup(int groupID);
}
}

View File

@ -0,0 +1,13 @@
using Demo.Domain.Models;
namespace Demo.Domain.UseCase
{
public interface IGroupUseCase
{
List<Group> GetAllGroups();
bool RemoveGroupByID(int groupID);
Group UpdateGroup(Group group);
Group GetGroupById(int groupID);
bool CreateGroup(string Name);
}
}

View File

@ -0,0 +1,16 @@
using Demo.Domain.Models;
namespace Demo.Domain.UseCase
{
public interface IPresenceUseCase
{
List<Presence> GetPresenceByGroup(int groupID);
List<Presence> GetPresenceByGroupByTime(int groupID, DateOnly date);
List<Presence> GetPresenceByUser(Guid userGuid);
List<Presence> GetFalsePresenceByUser(Guid userGuid);
List<Presence> GetFalsePresenceByGroup(int groupID);
bool IsAttedance(int firstLesson, int lastLesson, DateOnly date, Guid UserGuid);
bool GeneratePresence(int firstLesson, int lastLesson, int groupID, DateOnly date);
bool GeneratePresenceWeek(int firstLesson, int lastLesson, int groupID, DateOnly date);
}
}

View File

@ -0,0 +1,13 @@
using Demo.Domain.Models;
namespace Demo.Domain.UseCase
{
public interface IUserUseCase
{
List<User> GetAllUsers();
bool RemoveUserByGuid(Guid userGuid);
User UpdateUser(User user);
User GetUserByGuid(Guid userGuid);
List<User> GetUsersByGroupID(int groupID);
}
}

View File

@ -0,0 +1,188 @@
using System.Security.Cryptography.X509Certificates;
using Demo.Data.Repository;
using Demo.Domain.Models;
namespace Demo.Domain.UseCase
{
public class PresenceUseCase : IPresenceUseCase
{
private readonly IUserRepository _repositoryUserImpl;
private readonly IPresenceRepository _repositoryPresenceImpl;
private readonly IGroupRepository _repositoryGroupImpl;
public PresenceUseCase(IPresenceRepository repositoryPresenceImpl, IUserRepository repositoryUserImpl, IGroupRepository repositoryGroupImpl)
{
_repositoryPresenceImpl = repositoryPresenceImpl;
_repositoryUserImpl = repositoryUserImpl;
_repositoryGroupImpl = repositoryGroupImpl;
}
public List<Presence> GetPresenceByGroup(int groupID){
var usersByGroup = _repositoryUserImpl.GetAllUser()
.Where(user => user.GroupID == groupID).ToList();
var presenceByGroup = _repositoryPresenceImpl.GetAllPresences()
.Where(x => usersByGroup.Any(user => user.Guid == x.UserGuid))
.Select(presence => new Presence{
User = new User{
Guid = presence.UserGuid,
Group = new Group{
ID = groupID,
Name = _repositoryGroupImpl.GetAllGroup().First(group => group.ID == groupID).Name
},
FIO = usersByGroup.First(user => user.Guid == presence.UserGuid).FIO,
},
LessonNumber = presence.LessonNumber,
Date = presence.Date,
IsAttedance = presence.IsAttedance
}).ToList();
return presenceByGroup;
}
public List<Presence> GetFalsePresenceByGroup(int groupID){
var usersByGroup = _repositoryUserImpl.GetAllUser()
.Where(user => user.GroupID == groupID).ToList();
var presenceByGroup = _repositoryPresenceImpl.GetAllPresences()
.Where(x => usersByGroup.Any(user => user.Guid == x.UserGuid) && x.IsAttedance == false)
.Select(presence => new Presence{
User = new User{
Guid = presence.UserGuid,
Group = new Group{
ID = groupID,
Name = _repositoryGroupImpl.GetAllGroup().First(group => group.ID == groupID).Name
},
FIO = usersByGroup.First(user => user.Guid == presence.UserGuid).FIO,
},
LessonNumber = presence.LessonNumber,
Date = presence.Date,
IsAttedance = presence.IsAttedance
}).ToList();
return presenceByGroup;
}
public List<Presence> GetPresenceByUser(Guid userGuid){
var user = _repositoryUserImpl.GetUserByGuid(userGuid);
var presenceByUser = _repositoryPresenceImpl.GetAllPresences()
.Where(user => userGuid == user.UserGuid)
.Select(presence => new Presence{
User = new User{
Guid = user.Guid,
Group = new Group{
ID = user.GroupID,
Name = _repositoryGroupImpl.GetAllGroup().First(group => group.ID == user.GroupID).Name
},
FIO = user.FIO
},
LessonNumber = presence.LessonNumber,
Date = presence.Date,
IsAttedance = presence.IsAttedance
}).ToList();
return presenceByUser;
}
public List<Presence> GetFalsePresenceByUser(Guid userGuid){
var user = _repositoryUserImpl.GetUserByGuid(userGuid);
var presenceByUser = _repositoryPresenceImpl.GetAllPresences()
.Where(user => userGuid == user.UserGuid && user.IsAttedance == false)
.Select(presence => new Presence{
User = new User{
Guid = user.Guid,
Group = new Group{
ID = user.GroupID,
Name = _repositoryGroupImpl.GetAllGroup().First(group => group.ID == user.GroupID).Name
},
FIO = user.FIO
},
LessonNumber = presence.LessonNumber,
Date = presence.Date,
IsAttedance = presence.IsAttedance
}).ToList();
return presenceByUser;
}
public List<Presence> GetPresenceByGroupByTime(int groupID, DateOnly date){
var usersByGroup = _repositoryUserImpl.GetAllUser()
.Where(user => user.GroupID == groupID).ToList();
var presenceByGroup = _repositoryPresenceImpl.GetAllPresences()
.Where(x => usersByGroup.Any(user => user.Guid == x.UserGuid && x.Date == date))
.Select(presence => new Presence{
User = new User{
Guid = presence.UserGuid,
Group = new Group{
ID = groupID,
Name = _repositoryGroupImpl.GetAllGroup().First(group => group.ID == groupID).Name
},
FIO = usersByGroup.First(user => user.Guid == presence.UserGuid).FIO,
},
LessonNumber = presence.LessonNumber,
Date = presence.Date,
IsAttedance = presence.IsAttedance
}).ToList();
return presenceByGroup;
}
public bool IsAttedance(int firstLesson, int lastLesson, DateOnly date, Guid UserGuid){
_repositoryPresenceImpl.IsAttedance(firstLesson, lastLesson, date, UserGuid);
return true;
}
public bool GeneratePresence(int firstLesson, int lastLesson, int groupID, DateOnly date)
{
var usersByGroup = _repositoryUserImpl.GetAllUser().Where(x => x.GroupID == groupID).ToList();
var groupName = _repositoryGroupImpl.GetAllGroup().First(group => group.ID == groupID).Name;
List<Presence> presenceList = new List<Presence>();
for (int i = firstLesson; i <= lastLesson; i++)
{
foreach (UserLocalEntity user in usersByGroup)
{
presenceList.Add(new Presence
{
User = new User
{
Group = new Group
{
ID = groupID,
Name = groupName
},
FIO = user.FIO,
Guid = user.Guid
},
IsAttedance = true,
Date = date,
LessonNumber = i
});
}
}
var presenceLocalEntity = presenceList.Select(x => new PresenceLocalEntity
{
UserGuid = x.User.Guid,
IsAttedance = x.IsAttedance,
LessonNumber = x.LessonNumber,
Date = x.Date
}).ToList();
_repositoryPresenceImpl.GeneratePresence(presenceLocalEntity);
return true;
}
public bool GeneratePresenceWeek(int firstLesson, int lastLesson, int groupID, DateOnly date){
for (int i = 0; i < 8; i++){
GeneratePresence(firstLesson, lastLesson, groupID, date.AddDays(i));
}
return true;
}
}
}

View File

@ -0,0 +1,94 @@
using Demo.Domain.Models;
using Demo.Data.Repository;
namespace Demo.Domain.UseCase
{
public class UserUseCase : IUserUseCase
{
private readonly IUserRepository _repositoryUserImpl;
private readonly IGroupRepository _repositoryGroupImpl;
public UserUseCase(IGroupRepository repositoryGroupImpl, IUserRepository repositoryUserImpl)
{
_repositoryGroupImpl = repositoryGroupImpl;
_repositoryUserImpl = repositoryUserImpl;
}
public List<Group> GetAllGroups() => _repositoryGroupImpl.GetAllGroup()
.Select(it => new Group{ID = it.ID, Name = it.Name}).ToList();
public List<User> GetAllUsers() => _repositoryUserImpl.GetAllUser()
.Join(_repositoryGroupImpl.GetAllGroup(),
user => user.GroupID,
group => group.ID,
(user, group) => new User{
FIO = user.FIO,
Guid = user.Guid,
Group = new Group{
ID = group.ID,
Name = group.Name}
}
).ToList();
public User GetUserByGuid(Guid userGuid){
UserLocalEntity? userLocalEntity = _repositoryUserImpl.GetUserByGuid(userGuid);
if (userLocalEntity == null) throw new Exception("bello");
Group? group = GetAllGroups().FirstOrDefault(it => userLocalEntity.GroupID == it.ID);
if (group == null) throw new Exception("bello");
return new User{
FIO = userLocalEntity.FIO,
Guid = userLocalEntity.Guid,
Group = new Group{
ID = group.ID,
Name = group.Name}
};
}
public List<User> GetUsersByGroupID(int groupID){
List<UserLocalEntity> localUsers = _repositoryUserImpl.GetUsersByGroupID(groupID);
if (localUsers == null) throw new Exception("bello");
Group? group = GetAllGroups().FirstOrDefault(it => groupID == it.ID);
if (group == null) throw new Exception("bello");
List<User> users = localUsers.Select(userLocal => new User{
FIO = userLocal.FIO,
Guid = userLocal.Guid,
Group = new Group{
Name = group.Name,
ID = group.ID
}
}).ToList();
return users;
}
public bool RemoveUserByGuid(Guid userGuid) {
return _repositoryUserImpl.RemoveUserByGuid(userGuid);
}
public User UpdateUser(User user)
{
UserLocalEntity userLocalEntity = new UserLocalEntity
{
FIO = user.FIO,
Guid = user.Guid,
GroupID = user.Group.ID
};
UserLocalEntity? result = _repositoryUserImpl.UpdateUser(userLocalEntity);
if (result == null)
{
throw new Exception("Не удалось обновить пользователя: пользователь не найден.");
}
Group? group = GetAllGroups().FirstOrDefault(it => result.GroupID == it.ID);
if (group == null)
{
throw new Exception("Не удалось обновить пользователя: группа не найдена.");
}
return new User
{
FIO = result.FIO,
Guid = result.Guid,
Group = group
};
}
}
}

17
domain/domain.csproj Normal file
View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\data\data.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ClosedXML" Version="0.104.1" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

40
presence.sln Normal file
View File

@ -0,0 +1,40 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "domain", "domain\domain.csproj", "{90F2D7E7-4D8A-40E6-87A0-2417E32C98C7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ui", "ui\ui.csproj", "{4E82627C-4A8E-4372-99D3-2FB5414F556B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "console_ui", "console_ui\console_ui.csproj", "{314AB1A4-CD9E-47D3-BDDB-5829803ADFB7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "data", "data\data.csproj", "{7FD5C1C4-6DF8-42BD-AD74-6D33CDE48894}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{90F2D7E7-4D8A-40E6-87A0-2417E32C98C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90F2D7E7-4D8A-40E6-87A0-2417E32C98C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90F2D7E7-4D8A-40E6-87A0-2417E32C98C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90F2D7E7-4D8A-40E6-87A0-2417E32C98C7}.Release|Any CPU.Build.0 = Release|Any CPU
{4E82627C-4A8E-4372-99D3-2FB5414F556B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E82627C-4A8E-4372-99D3-2FB5414F556B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E82627C-4A8E-4372-99D3-2FB5414F556B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E82627C-4A8E-4372-99D3-2FB5414F556B}.Release|Any CPU.Build.0 = Release|Any CPU
{314AB1A4-CD9E-47D3-BDDB-5829803ADFB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{314AB1A4-CD9E-47D3-BDDB-5829803ADFB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{314AB1A4-CD9E-47D3-BDDB-5829803ADFB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{314AB1A4-CD9E-47D3-BDDB-5829803ADFB7}.Release|Any CPU.Build.0 = Release|Any CPU
{7FD5C1C4-6DF8-42BD-AD74-6D33CDE48894}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7FD5C1C4-6DF8-42BD-AD74-6D33CDE48894}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FD5C1C4-6DF8-42BD-AD74-6D33CDE48894}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7FD5C1C4-6DF8-42BD-AD74-6D33CDE48894}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

18
ui/AdminConsole.cs Normal file
View File

@ -0,0 +1,18 @@
using Demo.Domain.UseCase;
namespace Demo.UI
{
public class AdminConsoleUI
{
IAdminUseCase _adminUseCase;
public AdminConsoleUI(IAdminUseCase adminUseCase) {
_adminUseCase = adminUseCase;
}
public void ExcelExport(int groupID) {
string output = _adminUseCase.ExcelExport(groupID) ? "Таблица создана" : "Таблица не создана";
Console.WriteLine(output);
}
}
}

105
ui/MainMenu.cs Normal file
View File

@ -0,0 +1,105 @@
using Demo.Domain.Models;
using Demo.Domain.UseCase;
namespace Demo.UI
{
public class MainMenuUI
{
UserConsoleUI _userConsoleUI;
GroupConsoleUI _groupConsoleUI;
PresenceConsoleUI _presenceConsoleUI;
AdminConsoleUI _adminConsoleUI;
public MainMenuUI(IUserUseCase userUseCase, IGroupUseCase groupUseCase, IPresenceUseCase presenceUseCase, IAdminUseCase adminUseCase) {
_userConsoleUI = new UserConsoleUI(userUseCase);
_groupConsoleUI = new GroupConsoleUI(groupUseCase, userUseCase, presenceUseCase);
_presenceConsoleUI = new PresenceConsoleUI(presenceUseCase);
_adminConsoleUI = new AdminConsoleUI(adminUseCase);
SelectRole();
}
private void SelectRole()
{
Console.WriteLine("Выберите роль:\n1: user\n2: admin");
string role = Console.ReadLine();
if (role == "1")
{
DisplayMenu();
}
else if (role == "2")
{
DisplayAdminMenu();
}
else
{
Console.WriteLine("Неверная роль. Попробуйте еще раз.");
SelectRole();
}
}
private void DisplayAdminMenu()
{
Console.WriteLine("0) Создать таблицу посещаемости для группы");
while(true)
{
switch (Console.ReadLine())
{
case "0": Console.WriteLine("Введите номер группы");
_adminConsoleUI.ExcelExport(Convert.ToInt32(Console.ReadLine())); break;
default: DisplayAdminMenu();
break;
}
}
}
private void DisplayMenu() {
Console.WriteLine("0) Вывести всё о группе\n1) Вывести все группы\n2) Cоздать новую группу\n3) Обновить имя группы\n4) Вывести группу по ID\n5) Удалить группу по ID\n6) Вывести всех юзеров\n7) Вывести юзера по GUID\n8) Обновить юзера по GUID\n9) Удалить юзера по GUID\n10) Тебе этого не надо\n11) Вывести посещаемость по группе\n12) Вывести посещаемость по группе и времени\n13) Генерация посещаемости\n14) Генерация посещаемости на неделю\n15) Смена посещаемости юзера");
while (true)
{
switch (Console.ReadLine())
{
case "0": Console.WriteLine("Введите номер группы");
_groupConsoleUI.DisplayAllBoutGroup(Convert.ToInt32(Console.ReadLine())); break;
case "1": _groupConsoleUI.DisplayAllGroups(); break;
case "2": Console.WriteLine("Введите имя группы");
_groupConsoleUI.CreateNewGroup(Console.ReadLine()); break;
case "3": Console.WriteLine("Введите номер и имя группы");
_groupConsoleUI.UpdateGroupName(Group.Parse(Console.ReadLine())); break;
case "4": Console.WriteLine("Введите номер группы");
_groupConsoleUI.DisplayGroupByID(Convert.ToInt32(Console.ReadLine())); break;
case "5": Console.WriteLine("Введите номер группы");
_groupConsoleUI.RemoveGroupByID(Convert.ToInt32(Console.ReadLine())); break;
case "6": _userConsoleUI.DisplayAllUsers(); break;
case "7": Console.WriteLine("Введите Guid юзера");
_userConsoleUI.DisplayUserByGuid(Guid.Parse(Console.ReadLine())); break;
case "8": Console.WriteLine("Введите Guid юзера");
_userConsoleUI.UpdateUserByGuid(User.Parse(Console.ReadLine())); break;
case "9": Console.WriteLine("Введите Guid юзера");
_userConsoleUI.RemoveUserByGuid(Guid.Parse(Console.ReadLine())); break;
case "10": Console.WriteLine("писяпопакака"); break;
case "11": Console.WriteLine("Введите номер группы");
_presenceConsoleUI.DisplayPresenceByGroup(Convert.ToInt32(Console.ReadLine())); break;
case "12": Console.WriteLine("Введите номер группы и дату");
_presenceConsoleUI.DisplayPresenceByGroupByTime(Convert.ToInt32(Console.ReadLine()), DateOnly.FromDateTime(Convert.ToDateTime(Console.ReadLine()))); break;
case "13": Console.WriteLine("Введите первый и последний урок, номер группы и дату");
_presenceConsoleUI.GeneratePresence(Convert.ToInt32(Console.ReadLine()), Convert.ToInt32(Console.ReadLine()), Convert.ToInt32(Console.ReadLine()), DateOnly.FromDateTime(Convert.ToDateTime(Console.ReadLine()))); break;
case "14": Console.WriteLine("Введите первый и последний урок, номер группы и дату");
_presenceConsoleUI.GeneratePresenceWeek(Convert.ToInt32(Console.ReadLine()), Convert.ToInt32(Console.ReadLine()), Convert.ToInt32(Console.ReadLine()), DateOnly.FromDateTime(Convert.ToDateTime(Console.ReadLine()))); break;
case "15": Console.WriteLine("Введите первый и последний урок, дату и Guid юзера");
_presenceConsoleUI.IsAttedance(Convert.ToInt32(Console.ReadLine()), Convert.ToInt32(Console.ReadLine()), DateOnly.FromDateTime(Convert.ToDateTime(Console.ReadLine())), Guid.Parse(Console.ReadLine())); break;
default: DisplayMenu();
break;
}
}
}
}
}

172
ui/UserConsole.cs Normal file
View File

@ -0,0 +1,172 @@
using System.ComponentModel.DataAnnotations;
using System.Text;
using Demo.Domain.Models;
using Demo.Domain.UseCase;
namespace Demo.UI
{
public class UserConsoleUI
{
IUserUseCase _userUseCase;
public UserConsoleUI(IUserUseCase userUseCase) {
_userUseCase = userUseCase;
}
public void DisplayAllUsers()
{
StringBuilder userOutput = new StringBuilder();
foreach (var user in _userUseCase.GetAllUsers())
{
userOutput.AppendLine($"{user.Guid}\t{user.FIO}\t{user.Group.Name}");
}
Console.WriteLine(userOutput);
}
public void RemoveUserByGuid(Guid guidUser) {
string output = _userUseCase.RemoveUserByGuid(guidUser) ? "Пользователь удален" : "Пользователь не удален";
Console.WriteLine(output);
}
public void UpdateUserByGuid(User user)
{
try
{
User output = _userUseCase.UpdateUser(user);
StringBuilder userOutput = new StringBuilder();
userOutput.AppendLine($"Обновленный пользователь: {output.Guid}\t{output.FIO}\t{output.Group.Name}");
Console.WriteLine(userOutput);
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при обновлении пользователя: {ex.Message}");
}
}
public void DisplayUserByGuid(Guid guid){
User output = _userUseCase.GetUserByGuid(guid);
StringBuilder userOutput = new StringBuilder();
userOutput.AppendLine($"{output.Guid}\t{output.FIO}\t{output.Group.Name}");
Console.WriteLine(userOutput);
}
}
public class GroupConsoleUI
{
IGroupUseCase _groupUseCase;
IUserUseCase _userUseCase;
IPresenceUseCase _presenceUseCase;
public GroupConsoleUI(IGroupUseCase groupUseCase, IUserUseCase userUseCase, IPresenceUseCase presenceUseCase){
_groupUseCase = groupUseCase;
_userUseCase = userUseCase;
_presenceUseCase = presenceUseCase;
}
public void DisplayAllGroups(){
StringBuilder userOutput = new StringBuilder();
foreach (var group in _groupUseCase.GetAllGroups())
{
userOutput.AppendLine($"{group.ID}\t{group.Name}");
}
Console.WriteLine(userOutput);
}
public void DisplayGroupByID(int ID){
StringBuilder userOutput = new StringBuilder();
var group = _groupUseCase.GetGroupById(ID);
{
userOutput.AppendLine($"{group.ID}\t{group.Name}");
}
Console.WriteLine(userOutput);
}
public void CreateNewGroup(string Name){
string output = _groupUseCase.CreateGroup(Name) ? "Группа создана" : "Группа не создана";
Console.WriteLine(output);
}
public void UpdateGroupName(Group group)
{
try
{
Group output = _groupUseCase.UpdateGroup(group);
StringBuilder groupOutput = new StringBuilder();
groupOutput.AppendLine($"Обновленная группа: {output.ID}\t{output.Name}");
Console.WriteLine(groupOutput);
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при обновлении группы: {ex.Message}");
}
}
public void RemoveGroupByID(int ID){
string output = _groupUseCase.RemoveGroupByID(ID) ? "Группа удалена" : "Группа не удалена";
Console.WriteLine(output);
}
public void DisplayAllBoutGroup(int groupID){
var users = _userUseCase.GetUsersByGroupID(groupID);
Console.WriteLine($"Группа: {groupID}\tКоличество учеников: {users.Count}");
var presencesByGroup = _presenceUseCase.GetPresenceByGroup(groupID);
var presenceFalseByGroup = _presenceUseCase.GetFalsePresenceByGroup(groupID);
var precentePresenceGroup = 100 - Math.Round((double)presenceFalseByGroup.Count / presencesByGroup.Count * 100);
Console.WriteLine($"Количество занятий: {presencesByGroup.Count}\tОбщий процент посещаемости: {precentePresenceGroup}");
foreach(var user in _userUseCase.GetUsersByGroupID(groupID)){
var countPresences = _presenceUseCase.GetPresenceByUser(user.Guid);
var countFalsePresences = _presenceUseCase.GetFalsePresenceByUser(user.Guid);
var precentePresenceUser = 100 - Math.Round((double)countFalsePresences.Count / countPresences.Count * 100);
if (precentePresenceUser < 40)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"FIO: {user.FIO}\tКоличество посещённых занятий: {countPresences.Count - countFalsePresences.Count}\tКоличество пропущенных занятий: {countFalsePresences.Count}\tПроцент посещаемости: {precentePresenceUser}");
Console.ResetColor();
}
else
{
Console.WriteLine($"FIO: {user.FIO}\tКоличество посещённых занятий: {countPresences.Count - countFalsePresences.Count}\tКоличество пропущенных занятий: {countFalsePresences.Count}\tПроцент посещаемости: {precentePresenceUser}");
}
}
}
}
public class PresenceConsoleUI{
IPresenceUseCase _presenceUseCase;
public PresenceConsoleUI (IPresenceUseCase presenceUseCase){
_presenceUseCase = presenceUseCase;
}
public void DisplayPresenceByGroup(int groupID){
StringBuilder stringBuilder = new StringBuilder();
foreach(Presence presence in _presenceUseCase.GetPresenceByGroup(groupID)){
stringBuilder.AppendLine($"{presence.User.FIO}, {presence.User.Group.Name}, {presence.IsAttedance}, {presence.Date}, {presence.LessonNumber}");
}
Console.WriteLine(stringBuilder);
}
public void DisplayPresenceByGroupByTime(int groupID, DateOnly date){
StringBuilder stringBuilder = new StringBuilder();
foreach(Presence presence in _presenceUseCase.GetPresenceByGroupByTime(groupID, date)){
stringBuilder.AppendLine($"{presence.User.FIO}, {presence.User.Group.Name}, {presence.IsAttedance}, {presence.Date}, {presence.LessonNumber}");
}
Console.WriteLine(stringBuilder);
}
public void GeneratePresence(int firstLesson, int lastLesson, int groupID, DateOnly date){
string output = _presenceUseCase.GeneratePresence(firstLesson, lastLesson, groupID, date) ? "Сгенерированно" : "Не сгенерированно";
Console.WriteLine(output);
}
public void GeneratePresenceWeek(int firstLesson, int lastLesson, int groupID, DateOnly date){
string output = _presenceUseCase.GeneratePresenceWeek(firstLesson, lastLesson, groupID, date) ? "Сгенерированно" : "Не сгенерированно";
Console.WriteLine(output);
}
public void IsAttedance(int firstLesson, int lastLesson, DateOnly date, Guid UserGuid){
string output = _presenceUseCase.IsAttedance(firstLesson, lastLesson, date, UserGuid) ? "Обновлено" : "Не обновлено";
Console.WriteLine(output);
}
}
}

13
ui/ui.csproj Normal file
View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\domain\domain.csproj" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>