diff --git a/.gitignore b/.gitignore index a4e3726..4de3441 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea/ .vs/ +.vscode/ [Bb]in/ [Oo]bj/ \ No newline at end of file diff --git a/Presence.API/Controllers/AdminController.cs b/Presence.API/Controllers/AdminController.cs index 8505728..deea5ef 100644 --- a/Presence.API/Controllers/AdminController.cs +++ b/Presence.API/Controllers/AdminController.cs @@ -1,4 +1,6 @@ -using Microsoft.AspNetCore.Mvc; +using domain.UseCase; +using domain.Request; +using Microsoft.AspNetCore.Mvc; namespace Presence.API.Controllers { @@ -6,5 +8,31 @@ namespace Presence.API.Controllers [Route("api/[controller]")] public class AdminController : ControllerBase { + private readonly IAdminUseCase _adminUseCase; + + public AdminController(IAdminUseCase adminUseCase) + { + _adminUseCase = adminUseCase; + } + + [HttpPost("/group/{groupId}/students")] + public IActionResult AddStudentsToGroup(int groupId, [FromBody] AddStudentsToGroupRequest request) + { + if (request?.Students == null) + return BadRequest(); + + _adminUseCase.AddStudentsToGroup(groupId, request); + return NoContent(); + } + + [HttpPost("/group/{groupId}/subjects")] + public IActionResult AddSubjectsToGroup(int groupId, [FromBody] AddSubjectsToGroupRequest request) + { + if (request?.Subjects == null) + return BadRequest(); + + _adminUseCase.AddSubjectsToGroup(groupId, request); + return NoContent(); + } } -} +} \ No newline at end of file diff --git a/Presence.API/Controllers/GroupController.cs b/Presence.API/Controllers/GroupController.cs index 2dd382d..08471eb 100644 --- a/Presence.API/Controllers/GroupController.cs +++ b/Presence.API/Controllers/GroupController.cs @@ -1,4 +1,4 @@ -using domain.Request; +using domain.Request; using domain.UseCase; using Microsoft.AspNetCore.Mvc; using Presence.API.Response; @@ -52,9 +52,41 @@ namespace Presence.API.Controllers if (addGroupRequest is null) return BadRequest(new ArgumentNullException()); - bool isCreated = _groupService.AddGroup(addGroupRequest); - if (isCreated) return CreatedAtAction(nameof(GetGroupByName), new { name = addGroupRequest.Name }, addGroupRequest ); - else return BadRequest(); + var groupWithStudentsRequest = new AddGroupWithStudentRequest + { + AddGroupRequest = new AddGroupRequest { Name = addGroupRequest.Name }, + AddStudentRequests = addGroupRequest.Students + }; + + _groupService.AddGroupWithStudents(groupWithStudentsRequest); + + var createdGroup = _groupService.GetGroupsWithStudents() + .FirstOrDefault(g => g.Name == addGroupRequest.Name); + + return CreatedAtAction(nameof(GetGroupById), new { id = createdGroup.Id }, createdGroup); + } + + [HttpGet("/group/{id:int}")] + public ActionResult GetGroupById(int id) + { + var group = _groupService.GetGroupsWithStudents().FirstOrDefault(g => g.Id == id); + if (group == null) + return NotFound(); + + var response = new GroupResponse + { + Id = group.Id, + Name = group.Name, + Users = group.Users?.Select( + user => new UserResponse + { + Id = user.Id, + LastName = user.LastName, + FirstName = user.FirstName, + Patronymic = user.Patronymic + }).ToList() + }; + return Ok(response); } [HttpGet("/group/{id}/subjects")] @@ -62,27 +94,5 @@ namespace Presence.API.Controllers { return Ok(_groupService.GetGroupSubject(id)); } - - [HttpGet("/group/{name}")] - public ActionResult GetGroupByName(string name) - { - var result = _groupService - .GetGroupsWithStudents() - .Where(g => g.Name == name) - .Select(group => new GroupResponse - { - Id = group.Id, - Name = group.Name, - Users = group.Users?.Select( - user => new UserResponse - { - Id = user.Id, - LastName = user.LastName, - FirstName = user.FirstName, - Patronymic = user.Patronymic - }).ToList() - }).ToList(); - return result.Count > 0 ? Ok(result) : NotFound(); - } } } diff --git a/Presence.API/Controllers/PresenceController.cs b/Presence.API/Controllers/PresenceController.cs index 5dcd62a..aa37e4b 100644 --- a/Presence.API/Controllers/PresenceController.cs +++ b/Presence.API/Controllers/PresenceController.cs @@ -1,4 +1,8 @@ -using Microsoft.AspNetCore.Mvc; +using domain.UseCase; +using Microsoft.AspNetCore.Mvc; +using Presence.API.Response; +using System; +using System.Linq; namespace Presence.API.Controllers { @@ -6,5 +10,33 @@ namespace Presence.API.Controllers [Route("api/[controller]")] public class PresenceController : ControllerBase { + private readonly IPresenceUseCase _presenceUseCase; + + public PresenceController(IPresenceUseCase presenceUseCase) + { + _presenceUseCase = presenceUseCase; + } + + [HttpGet("/presence/{groupId}")] + public ActionResult GetPresence( + int groupId, + [FromQuery] int? subject, + [FromQuery] DateTime? date, + [FromQuery] int? student) + { + var presences = _presenceUseCase.GetPresence(groupId, subject, date, student) + .Select(p => new PresenceResponse + { + Id = p.Id, + StudentId = p.StudentId, + StudentName = $"{p.Student.LastName} {p.Student.FirstName} {p.Student.Patronymic}", + SubjectId = p.SubjectId, + SubjectName = p.Subject.Name, + Date = p.Date + }) + .ToList(); + + return Ok(presences); + } } } diff --git a/Presence.API/Extensions/ServiceCollectionExtension.cs b/Presence.API/Extensions/ServiceCollectionExtension.cs index 0198cd3..4638645 100644 --- a/Presence.API/Extensions/ServiceCollectionExtension.cs +++ b/Presence.API/Extensions/ServiceCollectionExtension.cs @@ -14,9 +14,19 @@ namespace Presence.API.Extensions .AddDbContext() .AddScoped() .AddScoped() - .AddScoped() - .AddScoped() + .AddScoped(); + + services + .AddDbContext() + .AddScoped() + .AddScoped() .AddScoped(); + + services + .AddDbContext() + .AddScoped() + .AddScoped() + .AddScoped(); } } } diff --git a/Presence.API/Request/AddGroupRequest.cs b/Presence.API/Request/AddGroupRequest.cs deleted file mode 100644 index 2709e7d..0000000 --- a/Presence.API/Request/AddGroupRequest.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Presence.API.Request -{ - public class AddGroupRequest - { - public string Name { get; set; } - } -} diff --git a/Presence.API/Response/PresenceResponse.cs b/Presence.API/Response/PresenceResponse.cs new file mode 100644 index 0000000..c3da8f6 --- /dev/null +++ b/Presence.API/Response/PresenceResponse.cs @@ -0,0 +1,14 @@ +using System; + +namespace Presence.API.Response +{ + public class PresenceResponse + { + public int Id { get; set; } + public int StudentId { get; set; } + public string StudentName { get; set; } + public int SubjectId { get; set; } + public string SubjectName { get; set; } + public DateOnly Date { get; set; } + } +} diff --git a/data/Repository/IAdminRepository.cs b/data/Repository/IAdminRepository.cs new file mode 100644 index 0000000..0d85753 --- /dev/null +++ b/data/Repository/IAdminRepository.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace data.Repository +{ + public interface IAdminRepository + { + void AddStudentsToGroup(int groupId, IEnumerable studentIds); + void AddSubjectsToGroup(int groupId, IEnumerable subjectIds); + } +} diff --git a/data/Repository/IPresenceRepository.cs b/data/Repository/IPresenceRepository.cs new file mode 100644 index 0000000..a0ca0a7 --- /dev/null +++ b/data/Repository/IPresenceRepository.cs @@ -0,0 +1,15 @@ +using data.DAO; +using System; +using System.Collections.Generic; + +namespace data.Repository +{ + public interface IPresenceRepository + { + IEnumerable GetPresence( + int groupId, + int? subjectId = null, + DateTime? date = null, + int? studentId = null); + } +} diff --git a/data/Repository/SQLAdminRepository.cs b/data/Repository/SQLAdminRepository.cs new file mode 100644 index 0000000..eb17f3a --- /dev/null +++ b/data/Repository/SQLAdminRepository.cs @@ -0,0 +1,58 @@ +using data.Repository; +using data.DAO; +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using System.Linq; + +namespace data.Repository +{ + public class SQLAdminRepository : IAdminRepository + { + private readonly DatabaseContext _context; + + public SQLAdminRepository(DatabaseContext context) + { + _context = context; + } + + public void AddStudentsToGroup(int groupId, IEnumerable studentIds) + { + var group = _context.Groups.Include(g => g.Students).FirstOrDefault(g => g.Id == groupId); + if (group == null) return; + + var studentsToAdd = _context.Students + .Where(u => studentIds.Contains(u.Id)) + .ToList(); + + foreach (var student in studentsToAdd) + { + if (!group.Students.Any(u => u.Id == student.Id)) + { + group.Students.Add(student); + } + } + + _context.SaveChanges(); + } + + public void AddSubjectsToGroup(int groupId, IEnumerable subjectIds) + { + var group = _context.Groups.Include(g => g.StudentGroupsSubjects).ThenInclude(s => s.Subject).FirstOrDefault(g => g.Id == groupId); + if (group == null) return; + + var subjectsToAdd = _context.Subjects + .Where(s => subjectIds.Contains(s.Id)) + .ToList(); + + foreach (var subject in subjectsToAdd) + { + if (!group.StudentGroupsSubjects.Any(s => s.Subject.Id == subject.Id)) + { + group.StudentGroupsSubjects.Add(new StudentGroupSubject { Subject = subject }); + } + } + + _context.SaveChanges(); + } + } +} diff --git a/data/Repository/SQLPresenceRepository.cs b/data/Repository/SQLPresenceRepository.cs new file mode 100644 index 0000000..211d1d0 --- /dev/null +++ b/data/Repository/SQLPresenceRepository.cs @@ -0,0 +1,42 @@ +using data.DAO; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace data.Repository +{ + public class SQLPresenceRepository : IPresenceRepository + { + private readonly DatabaseContext _context; + + public SQLPresenceRepository(DatabaseContext context) + { + _context = context; + } + + public IEnumerable GetPresence( + int groupId, + int? subjectId = null, + DateTime? date = null, + int? studentId = null) + { + var query = _context.Diaries + .Include(p => p.Student) + .Include(p => p.StudentGroupSubject) + .ThenInclude(p => p.Subject) + .Where(p => p.Student.GroupId == groupId); + + if (subjectId.HasValue) + query = query.Where(p => p.StudentGroupSubject.Subject.Id == subjectId.Value); + + if (date.HasValue) + query = query.Where(p => p.Date == DateOnly.FromDateTime(date.Value)); + + if (studentId.HasValue) + query = query.Where(p => p.Student.Id == studentId.Value); + + return query.ToList(); + } + } +} diff --git a/domain/Entity/PresenceEntity.cs b/domain/Entity/PresenceEntity.cs new file mode 100644 index 0000000..3a15756 --- /dev/null +++ b/domain/Entity/PresenceEntity.cs @@ -0,0 +1,14 @@ +using System; + +namespace domain.Entity +{ + public class PresenceEntity + { + public int Id { get; set; } + public int StudentId { get; set; } + public UserEntity Student { get; set; } + public int SubjectId { get; set; } + public SubjectEntity Subject { get; set; } + public DateOnly Date { get; set; } + } +} diff --git a/domain/Request/AddGroupRequest.cs b/domain/Request/AddGroupRequest.cs index 2f47fb8..d5b4e5b 100644 --- a/domain/Request/AddGroupRequest.cs +++ b/domain/Request/AddGroupRequest.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,5 +9,6 @@ namespace domain.Request public class AddGroupRequest { public string Name { get; set; } + public List Students { get; set; } = new List(); } } diff --git a/domain/Request/AddStudentsToGroupRequest.cs b/domain/Request/AddStudentsToGroupRequest.cs new file mode 100644 index 0000000..69c9944 --- /dev/null +++ b/domain/Request/AddStudentsToGroupRequest.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace domain.Request +{ + public class AddStudentsToGroupRequest + { + public List Students { get; set; } = new List(); + } +} diff --git a/domain/Request/AddSubjectsToGroupRequest.cs b/domain/Request/AddSubjectsToGroupRequest.cs new file mode 100644 index 0000000..14796c9 --- /dev/null +++ b/domain/Request/AddSubjectsToGroupRequest.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace domain.Request +{ + public class AddSubjectsToGroupRequest + { + public List Subjects { get; set; } = new List(); + } +} diff --git a/domain/Service/AdminService.cs b/domain/Service/AdminService.cs new file mode 100644 index 0000000..98022d5 --- /dev/null +++ b/domain/Service/AdminService.cs @@ -0,0 +1,26 @@ +using data.Repository; +using domain.Request; +using domain.UseCase; + +namespace domain.Service +{ + public class AdminService : IAdminUseCase + { + private readonly IAdminRepository _adminRepository; + + public AdminService(IAdminRepository adminRepository) + { + _adminRepository = adminRepository; + } + + public void AddStudentsToGroup(int groupId, AddStudentsToGroupRequest request) + { + _adminRepository.AddStudentsToGroup(groupId, request.Students); + } + + public void AddSubjectsToGroup(int groupId, AddSubjectsToGroupRequest request) + { + _adminRepository.AddSubjectsToGroup(groupId, request.Subjects); + } + } +} diff --git a/domain/Service/PresenceService.cs b/domain/Service/PresenceService.cs new file mode 100644 index 0000000..0f9347a --- /dev/null +++ b/domain/Service/PresenceService.cs @@ -0,0 +1,46 @@ +using data.Repository; +using domain.Entity; +using domain.UseCase; +using System; +using System.Collections.Generic; + +namespace domain.Service +{ + public class PresenceService : IPresenceUseCase + { + private readonly IPresenceRepository _presenceRepository; + + public PresenceService(IPresenceRepository presenceRepository) + { + _presenceRepository = presenceRepository; + } + + public IEnumerable GetPresence( + int groupId, + int? subjectId = null, + DateTime? date = null, + int? studentId = null) + { + return _presenceRepository.GetPresence(groupId, subjectId, date, studentId).Select(p => new PresenceEntity + { + Id = p.Id, + StudentId = p.Student.Id, + Student = new UserEntity + { + Id = p.Student.Id, + FirstName = p.Student.FirstName, + LastName = p.Student.LastName, + Patronymic = p.Student.Patronymic, + Group = new GroupEntity() + }, + SubjectId = p.StudentGroupSubject.Subject.Id, + Subject = new SubjectEntity + { + Id = p.StudentGroupSubject.Subject.Id, + Name = p.StudentGroupSubject.Subject.Name + }, + Date = p.Date + }); + } + } +} diff --git a/domain/UseCase/IAdminUseCase.cs b/domain/UseCase/IAdminUseCase.cs new file mode 100644 index 0000000..1d69ac1 --- /dev/null +++ b/domain/UseCase/IAdminUseCase.cs @@ -0,0 +1,10 @@ +using domain.Request; + +namespace domain.UseCase +{ + public interface IAdminUseCase + { + void AddStudentsToGroup(int groupId, AddStudentsToGroupRequest request); + void AddSubjectsToGroup(int groupId, AddSubjectsToGroupRequest request); + } +} diff --git a/domain/UseCase/IGroupUseCase.cs b/domain/UseCase/IGroupUseCase.cs index 9d87f78..03dc5bc 100644 --- a/domain/UseCase/IGroupUseCase.cs +++ b/domain/UseCase/IGroupUseCase.cs @@ -1,4 +1,4 @@ -using domain.Entity; +using domain.Entity; using domain.Request; using System; using System.Collections.Generic; diff --git a/domain/UseCase/IPresenceUseCase.cs b/domain/UseCase/IPresenceUseCase.cs new file mode 100644 index 0000000..b4cd83b --- /dev/null +++ b/domain/UseCase/IPresenceUseCase.cs @@ -0,0 +1,15 @@ +using domain.Entity; +using System; +using System.Collections.Generic; + +namespace domain.UseCase +{ + public interface IPresenceUseCase + { + IEnumerable GetPresence( + int groupId, + int? subjectId = null, + DateTime? date = null, + int? studentId = null); + } +}