diff --git a/data/RemoteData/RemoteDataBase/DAO/User.cs b/data/RemoteData/RemoteDataBase/DAO/User.cs index 5c042d2..ea297e0 100644 --- a/data/RemoteData/RemoteDataBase/DAO/User.cs +++ b/data/RemoteData/RemoteDataBase/DAO/User.cs @@ -4,7 +4,7 @@ namespace Demo.Data.RemoteData.RemoteDataBase.DAO { public class UserDAO { - public string FIO { get; set; } + public string FIO { get; set; } public Guid Guid {get; set; } public int GroupID {get; set;} public GroupDAO Group {get; set; } diff --git a/data/Repository/IPresenceRepository.cs b/data/Repository/IPresenceRepository.cs index bce6080..8e63c14 100644 --- a/data/Repository/IPresenceRepository.cs +++ b/data/Repository/IPresenceRepository.cs @@ -7,5 +7,6 @@ namespace Demo.Data.Repository List GetAllPresences(); void IsAttedance(int firstLesson, int lastLesson, DateOnly date, Guid UserGuid); List GeneratePresence(List presenceLocalEntities); + bool DeletePresence(); } } \ No newline at end of file diff --git a/data/Repository/IUserRepository.cs b/data/Repository/IUserRepository.cs index 16629e7..9bebc91 100644 --- a/data/Repository/IUserRepository.cs +++ b/data/Repository/IUserRepository.cs @@ -8,6 +8,7 @@ namespace Demo.Data.Repository UserLocalEntity? GetUserByGuid(Guid guid); List GetUsersByGroupID(int groupID); bool RemoveUserByGuid(Guid guid); + public UserLocalEntity? CreateUser(string FIO, string GroupName); UserLocalEntity? UpdateUser(UserLocalEntity updatedUser); } } \ No newline at end of file diff --git a/data/Repository/PresenceRepositoryImpl.cs b/data/Repository/PresenceRepositoryImpl.cs index 1b00299..d4b2276 100644 --- a/data/Repository/PresenceRepositoryImpl.cs +++ b/data/Repository/PresenceRepositoryImpl.cs @@ -36,6 +36,13 @@ namespace Demo.Data.Repository return presenceLocalEntities; } + public bool DeletePresence(){ + var allRecords = _remoteDatabaseContext.PresenceDaos.ToList(); + _remoteDatabaseContext.PresenceDaos.RemoveRange(allRecords); + _remoteDatabaseContext.SaveChanges(); + return true; + } + public void IsAttedance(int firstLesson, int lastLesson, DateOnly date, Guid UserGuid){ var presencesToUpdate = _remoteDatabaseContext.PresenceDaos .Where(x => x.LessonNumber >= firstLesson diff --git a/data/Repository/UserRepositoryImpl.cs b/data/Repository/UserRepositoryImpl.cs index af195e3..22efaa1 100644 --- a/data/Repository/UserRepositoryImpl.cs +++ b/data/Repository/UserRepositoryImpl.cs @@ -1,6 +1,8 @@ using Demo.Domain.Models; using Demo.Data.LocalData; using Demo.Data.RemoteData.RemoteDataBase; +using Demo.Data.RemoteData.RemoteDataBase.DAO; + namespace Demo.Data.Repository { @@ -45,6 +47,14 @@ namespace Demo.Data.Repository return true; } + public UserLocalEntity? CreateUser(string FIO, string GroupName){ + var groupDAO = _remoteDatabaseContext.Groups.FirstOrDefault(x => x.Name == GroupName); + UserDAO userDAO = new UserDAO{FIO = FIO, Guid = Guid.NewGuid(), GroupID = groupDAO.ID}; + var result = _remoteDatabaseContext.Users.Add(userDAO); + _remoteDatabaseContext.SaveChanges(); + return new UserLocalEntity{FIO = FIO, Guid = Guid.NewGuid(), GroupID = groupDAO.ID}; + } + public UserLocalEntity? UpdateUser(UserLocalEntity updatedUser){ var user = _remoteDatabaseContext.Users.FirstOrDefault(x => x.Guid == updatedUser.Guid); if (user == null){ diff --git a/domain/Models/Group.cs b/domain/Models/Group.cs index ef15cfd..1cfc185 100644 --- a/domain/Models/Group.cs +++ b/domain/Models/Group.cs @@ -10,4 +10,21 @@ namespace Demo.Domain.Models return new Group{ID = Convert.ToInt32(words[0]), Name = words[1]}; } } + + public class GroupU{ + public required int ID{get; set; } + public required string Name{get; set; } + public List Users { get; set; } = new List(); + } + + public class GroupWithUsers + { + public required string GroupName { get; set; } + public List Users { get; set; } + } + + public class DeleteGroupsRequest + { + public List GroupIDs { get; set; } + } } \ No newline at end of file diff --git a/domain/Models/Presence.cs b/domain/Models/Presence.cs index 8fddb96..96aa6d6 100644 --- a/domain/Models/Presence.cs +++ b/domain/Models/Presence.cs @@ -8,4 +8,12 @@ namespace Demo.Domain.Models public required int LessonNumber { get; set; } } + + public class PresencePost + { + public required int firstLesson {get; set; } + public required int lastLesson {get; set; } + public required int groupID {get; set; } + public required DateOnly date {get; set; } + } } \ No newline at end of file diff --git a/domain/Models/User.cs b/domain/Models/User.cs index d1f6626..dbc22ad 100644 --- a/domain/Models/User.cs +++ b/domain/Models/User.cs @@ -35,4 +35,15 @@ namespace Demo.Domain.Models } } } + + public class UserRequest + { + public required string FIO{get; set; } + public required Group Group{get; set; } + } + + public class DeleteUsersRequest + { + public List UsersGuid { get; set; } + } } \ No newline at end of file diff --git a/domain/UseCase/GroupUseCase.cs b/domain/UseCase/GroupUseCase.cs index 8c2efc5..7585030 100644 --- a/domain/UseCase/GroupUseCase.cs +++ b/domain/UseCase/GroupUseCase.cs @@ -23,6 +23,21 @@ namespace Demo.Domain.UseCase return new Group{ID = groupID, Name = groupLocalEntity.Name}; } + public List GetAllGroupsWithUsers(){ + var groups = _repositoryGroupImpl.GetAllGroup().Select(it => new GroupU { ID = it.ID, Name = it.Name }).ToList(); + var users = _repositoryUserImpl.GetAllUser().Select(it => new User{FIO = it.FIO, Guid = it.Guid, Group = new Group{ID = it.GroupID, Name = _repositoryGroupImpl.GetGroupById(it.GroupID).Name}}).ToList(); + foreach (var group in groups) + { + foreach (var user in users) + { + if (user.Group.ID == group.ID){ + group.Users.Add(user); + } + } + } + return groups; + } + public bool CreateGroup(string Name){ _repositoryGroupImpl.CreateGroup(Name); return true; diff --git a/domain/UseCase/IGroupUseCase.cs b/domain/UseCase/IGroupUseCase.cs index c6d2d49..87bad98 100644 --- a/domain/UseCase/IGroupUseCase.cs +++ b/domain/UseCase/IGroupUseCase.cs @@ -8,6 +8,7 @@ namespace Demo.Domain.UseCase bool RemoveGroupByID(int groupID); Group UpdateGroup(Group group); Group GetGroupById(int groupID); + List GetAllGroupsWithUsers(); bool CreateGroup(string Name); } } \ No newline at end of file diff --git a/domain/UseCase/IPresenceUseCase.cs b/domain/UseCase/IPresenceUseCase.cs index 8a1d588..85af733 100644 --- a/domain/UseCase/IPresenceUseCase.cs +++ b/domain/UseCase/IPresenceUseCase.cs @@ -12,5 +12,6 @@ namespace Demo.Domain.UseCase 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); + bool DeletePresence(); } } \ No newline at end of file diff --git a/domain/UseCase/IUserUseCase.cs b/domain/UseCase/IUserUseCase.cs index 96a00b1..d9f755f 100644 --- a/domain/UseCase/IUserUseCase.cs +++ b/domain/UseCase/IUserUseCase.cs @@ -6,6 +6,7 @@ namespace Demo.Domain.UseCase { List GetAllUsers(); bool RemoveUserByGuid(Guid userGuid); + bool CreateUser(User user); User UpdateUser(User user); User GetUserByGuid(Guid userGuid); List GetUsersByGroupID(int groupID); diff --git a/domain/UseCase/PresenceUseCase.cs b/domain/UseCase/PresenceUseCase.cs index 7170fd6..f3170db 100644 --- a/domain/UseCase/PresenceUseCase.cs +++ b/domain/UseCase/PresenceUseCase.cs @@ -178,6 +178,10 @@ namespace Demo.Domain.UseCase return true; } + public bool DeletePresence(){ + return _repositoryPresenceImpl.DeletePresence(); + } + 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)); diff --git a/domain/UseCase/UserUseCase.cs b/domain/UseCase/UserUseCase.cs index c42523e..b9f0fbc 100644 --- a/domain/UseCase/UserUseCase.cs +++ b/domain/UseCase/UserUseCase.cs @@ -61,6 +61,11 @@ namespace Demo.Domain.UseCase return users; } + public bool CreateUser(User user){ + _repositoryUserImpl.CreateUser(user.FIO, user.Group.Name); + return true; + } + public bool RemoveUserByGuid(Guid userGuid) { return _repositoryUserImpl.RemoveUserByGuid(userGuid); } diff --git a/presence.sln b/presence.sln index 314432d..60018c0 100644 --- a/presence.sln +++ b/presence.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "console_ui", "console_ui\co EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "data", "data\data.csproj", "{7FD5C1C4-6DF8-42BD-AD74-6D33CDE48894}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "presence_api", "presence_api\presence_api.csproj", "{F7B9C650-020B-45AE-AB31-4C6DC1C1D4CE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -36,5 +38,9 @@ Global {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 + {F7B9C650-020B-45AE-AB31-4C6DC1C1D4CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7B9C650-020B-45AE-AB31-4C6DC1C1D4CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7B9C650-020B-45AE-AB31-4C6DC1C1D4CE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7B9C650-020B-45AE-AB31-4C6DC1C1D4CE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/presence_api/Controllers/AdminController.cs b/presence_api/Controllers/AdminController.cs new file mode 100644 index 0000000..c3a6061 --- /dev/null +++ b/presence_api/Controllers/AdminController.cs @@ -0,0 +1,113 @@ +using Demo.Domain.Models; +using Demo.Domain.UseCase; +using Microsoft.AspNetCore.Mvc; +using Npgsql.TypeMapping; + +namespace presence_api.Controllers; +[ApiController] +[Route("api/[controller]")] + +public class AdminController: ControllerBase{ + private readonly GroupUseCase _groupUseCase; + private readonly UserUseCase _userUseCase; + private readonly PresenceUseCase _presenceUseCase; + public AdminController(GroupUseCase groupUseCase, UserUseCase userUseCase, PresenceUseCase presenceUseCase){ + _groupUseCase = groupUseCase; + _userUseCase = userUseCase; + _presenceUseCase = presenceUseCase; + } + + //post + [HttpPost] + public ActionResult CreateGroup([FromBody] GroupWithUsers request) + { + if (request == null || string.IsNullOrEmpty(request.GroupName)) + { + return BadRequest("Invalid request"); + } + + bool isCreated = _groupUseCase.CreateGroup(request.GroupName); + + + foreach(var user in request.Users){ + var usert = new User{FIO = user.FIO, Guid = Guid.NewGuid(), Group = user.Group}; + _userUseCase.CreateUser(usert); + } + return Ok(isCreated); + } + + //delete + [HttpDelete("user")] + public ActionResult DeleteUser(Guid userGuid){ + if (userGuid == Guid.Empty){ + return BadRequest("Invalid request"); + } + bool isDeleted = _userUseCase.RemoveUserByGuid(userGuid); + if (isDeleted == false){ + return NotFound("User not found"); + } + return Ok(true); + } + + [HttpDelete("users")] + public ActionResult DeleteUsers([FromBody] DeleteUsersRequest request){ + if (request == null){ + return BadRequest("Invalid request"); + } + foreach (Guid userGuid in request.UsersGuid) + { + bool isDeleted = _userUseCase.RemoveUserByGuid(userGuid); + if (isDeleted == false){ + return NotFound("User not found"); + } + } + return Ok(true); + } + + [HttpDelete("group")] + public ActionResult DeleteGroup(int GroupID){ + bool isDeleted = _groupUseCase.RemoveGroupByID(GroupID); + if (isDeleted == false){ + return NotFound("Group not found"); + } + return Ok(true); + } + + [HttpDelete("groups")] + public ActionResult DeleteGroups([FromBody] DeleteGroupsRequest request){ + if (request == null){ + return BadRequest("Invalid request"); + } + foreach (int GroupID in request.GroupIDs) + { + bool isDeleted = _groupUseCase.RemoveGroupByID(GroupID); + if (isDeleted == false){ + return NotFound("Group not found"); + } + } + return Ok(true); + } + + [HttpDelete("presence")] + public ActionResult DeletePresence(){ + return Ok(_presenceUseCase.DeletePresence()); + } + + //get + [HttpGet] + public ActionResult> getGroupsWithUsers() + { + return Ok(_groupUseCase.GetAllGroupsWithUsers()); + } + + [HttpGet("user/{userGuid}")] + public ActionResult GetUserByGuid(Guid userGuid) + { + var user = _userUseCase.GetUserByGuid(userGuid); + if (user != null){ + return Ok(user); + } else{ + return NotFound("User not found"); + } + } +} \ No newline at end of file diff --git a/presence_api/Controllers/GroupController.cs b/presence_api/Controllers/GroupController.cs new file mode 100644 index 0000000..14be506 --- /dev/null +++ b/presence_api/Controllers/GroupController.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Mvc; +using Demo.Domain.UseCase; +using Demo.Domain.Models; + +namespace presence_api.Controllers; +[ApiController] +[Route("api/[controller]")] +public class GroupController: ControllerBase{ + +private readonly GroupUseCase _groupUseCase; + public GroupController(GroupUseCase groupUseCase){ + _groupUseCase = groupUseCase; + } + + [HttpGet] + public ActionResult> getGroups(){ + return Ok(_groupUseCase.GetAllGroups()); + } +} \ No newline at end of file diff --git a/presence_api/Program.cs b/presence_api/Program.cs new file mode 100644 index 0000000..c2f44fb --- /dev/null +++ b/presence_api/Program.cs @@ -0,0 +1,25 @@ +using Demo.Data.RemoteData.RemoteDataBase; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers(); + +builder.Services.AddDbContext(); +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +builder.Services.ConfigurateGroup(); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); +app.MapControllers(); + +app.Run(); + diff --git a/presence_api/Properties/launchSettings.json b/presence_api/Properties/launchSettings.json new file mode 100644 index 0000000..454f762 --- /dev/null +++ b/presence_api/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:46509", + "sslPort": 44380 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5192", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7147;http://localhost:5192", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/presence_api/ServiceExtensions/ServiceExtensions.cs b/presence_api/ServiceExtensions/ServiceExtensions.cs new file mode 100644 index 0000000..4d5b6b1 --- /dev/null +++ b/presence_api/ServiceExtensions/ServiceExtensions.cs @@ -0,0 +1,15 @@ +using Demo.Data.Repository; +using Demo.Domain.UseCase; + +public static class ServiceExtencions +{ + public static void ConfigurateGroup(this IServiceCollection services) + { + services.AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped(); + } +} \ No newline at end of file diff --git a/presence_api/appsettings.Development.json b/presence_api/appsettings.Development.json new file mode 100644 index 0000000..ff66ba6 --- /dev/null +++ b/presence_api/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/presence_api/appsettings.json b/presence_api/appsettings.json new file mode 100644 index 0000000..4d56694 --- /dev/null +++ b/presence_api/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/presence_api/presence_api.csproj b/presence_api/presence_api.csproj new file mode 100644 index 0000000..9b804d2 --- /dev/null +++ b/presence_api/presence_api.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/presence_api/presence_api.http b/presence_api/presence_api.http new file mode 100644 index 0000000..62b85fd --- /dev/null +++ b/presence_api/presence_api.http @@ -0,0 +1,6 @@ +@presence_api_HostAddress = http://localhost:5192 + +GET {{presence_api_HostAddress}}/weatherforecast/ +Accept: application/json + +###