diff --git a/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs b/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs index 6987480b971ac0672e38ee36c69abb23d750a41e..4dd5d23e98f3fa4396be61df98a4da0d5d72579d 100644 --- a/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs +++ b/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs @@ -81,64 +81,5 @@ namespace Tsi1.Api.Controllers return Ok(); } - [Authorize(Roles = UserTypes.Professor)] - [HttpPut("AddOrModifyGrade")] - public async Task<IActionResult> AddOrModifyGrade(GradeDto gradeDto) - { - var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); - var result = await _activityService.AddOrModifyGrade(gradeDto, userId); - - if (result.HasError) - { - return BadRequest(result.Message); - } - - return Ok(result.Data); - } - - [Authorize(Roles = UserTypes.Professor)] - [HttpDelete("DeleteGrade/{activityId}/{userId}")] - public async Task<IActionResult> DeleteGrade(int activityId, int userId) - { - var myUserId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); - var result = await _activityService.DeleteGrade(myUserId, activityId, userId); - - if (result.HasError) - { - return BadRequest(result.Message); - } - - return Ok(); - } - - [Authorize(Roles = UserTypes.Student)] - [HttpGet("GetMyGrades/{activityId}")] - public async Task<IActionResult> GetMyGrades(int activityId) - { - var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); - var result = await _activityService.GetMyGrades(activityId, userId); - - if (result.HasError) - { - return BadRequest(result.Message); - } - - return Ok(result.Data); - } - - [Authorize(Roles = UserTypes.Professor + ", " + UserTypes.FacultyAdmin)] - [HttpGet("GetAllGrades/{activityId}")] - public async Task<IActionResult> GetAllGrades(int activityId) - { - var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); - var result = await _activityService.GetAllGrades(activityId, userId); - - if (result.HasError) - { - return BadRequest(result.Message); - } - - return Ok(result.Data); - } } } diff --git a/Tsi1.Api/Tsi1.Api/Controllers/EvaluationController.cs b/Tsi1.Api/Tsi1.Api/Controllers/EvaluationController.cs new file mode 100644 index 0000000000000000000000000000000000000000..669c0e22058ae0a6b59d4c47c4e7163824bd8c10 --- /dev/null +++ b/Tsi1.Api/Tsi1.Api/Controllers/EvaluationController.cs @@ -0,0 +1,138 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Tsi1.BusinessLayer.Dtos; +using Tsi1.BusinessLayer.Helpers; +using Tsi1.BusinessLayer.Interfaces; + +namespace Tsi1.Api.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class EvaluationController : ControllerBase + { + private readonly IEvaluationService _evaluationService; + + public EvaluationController(IEvaluationService evaluationService) + { + _evaluationService = evaluationService; + } + + [Authorize(Roles = UserTypes.Student)] + [HttpPost("Registration/{evaluationId}")] + public async Task<IActionResult> GetAll(int evaluationId) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + + var result = await _evaluationService.Registration(evaluationId, userId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } + + [Authorize(Roles = UserTypes.Student)] + [HttpPost("CancelRegistration/{evaluationId}")] + public async Task<IActionResult> CancelRegistration(int evaluationId) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + + var result = await _evaluationService.CancelRegistration(evaluationId, userId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } + + [Authorize(Roles = UserTypes.Student)] + [HttpPost("SubmitLaboratory/{evaluationId}")] + public async Task<IActionResult> SubmitLaboratory(FileDto fileDto, int evaluationId) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + + var result = await _evaluationService.SubmitLaboratory(fileDto, evaluationId, userId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } + + [Authorize(Roles = UserTypes.Student)] + [HttpDelete("DeleteLaboratory/{submissionId}")] + public async Task<IActionResult> DeleteLaboratory(int submissionId) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + + var result = await _evaluationService.DeleteLaboratory(submissionId, userId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } + + [Authorize(Roles = UserTypes.Student)] + [HttpGet("GetMyEvaluationInscriptions/{courseId}")] + public async Task<IActionResult> GetMyEvaluationInscriptions(int courseId) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + + var result = await _evaluationService.GetMyEvaluationInscriptions(userId, courseId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } + + [Authorize(Roles = UserTypes.Professor)] + [HttpGet("GetAllEvaluationInscriptions/{evaluationId}")] + public async Task<IActionResult> GetAllEvaluationInscriptions(int evaluationId) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + + var result = await _evaluationService.GetAllEvaluationInscriptions(userId, evaluationId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } + + //QualifyEvaluationInscription(EvaluationInscriptionModifyDto evaluationInscriptionDto, int userId); + [Authorize(Roles = UserTypes.Professor)] + [HttpPost("QualifyEvaluationInscription")] + public async Task<IActionResult> SubmitLaboratory(EvaluationInscriptionModifyDto evaluationInscriptionDto) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + + var result = await _evaluationService.QualifyEvaluationInscription(evaluationInscriptionDto, userId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } + } +} diff --git a/Tsi1.Api/Tsi1.Api/Startup.cs b/Tsi1.Api/Tsi1.Api/Startup.cs index 5718b4a826b7bb99f6b3183540f37e2dfb3855f4..1f237eccf6808788164953e11f50f003db17c27f 100644 --- a/Tsi1.Api/Tsi1.Api/Startup.cs +++ b/Tsi1.Api/Tsi1.Api/Startup.cs @@ -106,6 +106,7 @@ namespace Tsi1.Api services.AddScoped<ICommunicationService, CommunicationService>(); services.AddScoped<IChatService, ChatService>(); services.AddScoped<IActivityService, ActivityService>(); + services.AddScoped<IEvaluationService, EvaluationService>(); services.AddSingleton<PresenceTracker>(); diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityCreateDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityCreateDto.cs index c320b4602d2b2bdfe628999a22f53a36eb728650..c6d043701593a89e2cfbae91d21e58304bc74450 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityCreateDto.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityCreateDto.cs @@ -11,5 +11,7 @@ namespace Tsi1.BusinessLayer.Dtos public bool IsVideoConference { get; set; } public int CourseId { get; set; } + + public EvaluationCreateDto Evaluation { get; set; } } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityModifyDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityModifyDto.cs index 084adde789d42cc7542cd6585e793690323a13d3..aa92abe101aef0d82ba09a7ce9ae68f6a166537f 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityModifyDto.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/ActivityModifyDto.cs @@ -9,5 +9,7 @@ namespace Tsi1.BusinessLayer.Dtos public string Name { get; set; } public bool IsVideoConference { get; set; } + + public EvaluationModifyDto Evaluation { get; set; } } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationCreateDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationCreateDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..a2f6abc93766959963674b6dc2687c3ade70601e --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationCreateDto.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.BusinessLayer.Dtos +{ + public class EvaluationCreateDto + { + public int EvaluationTypeId { get; set; } + + public bool IsCompleted { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationDetailDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationDetailDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..963bf1a8e857a4ec00e989ec6fc0a13dfa450318 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationDetailDto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.BusinessLayer.Dtos +{ + public class EvaluationDetailDto + { + public int Id { get; set; } + + public int EvaluationTypeId { get; set; } + + public bool IsCompleted { get; set; } + + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationInscriptionDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationInscriptionDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..4ce3191eead04de775708b35f1a5f44563803803 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationInscriptionDto.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.BusinessLayer.Dtos +{ + public class EvaluationInscriptionDto + { + public int EvaluationId { get; set; } + + public int StudentId { get; set; } + + public decimal Grade { get; set; } + + public bool HasAttended { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationInscriptionModifyDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationInscriptionModifyDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..1792396db86dbf97ee45aac714efb4ff86493f36 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationInscriptionModifyDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.BusinessLayer.Dtos +{ + public class EvaluationInscriptionModifyDto + { + public int EvaluationId { get; set; } + + public int StudentId { get; set; } + + public decimal Grade { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationModifyDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationModifyDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..9ebaf996ef6a8b82555a38e395622cf374289b5f --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationModifyDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.BusinessLayer.Dtos +{ + public class EvaluationModifyDto + { + public int Id { get; set; } + + public int EvaluationTypeId { get; set; } + + public bool IsCompleted { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationTypeDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationTypeDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..2f678c32cbf5674b2d3683e77df4ef7cf916d115 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/EvaluationTypeDto.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.BusinessLayer.Dtos +{ + public class EvaluationTypeDto + { + public int Id { get; set; } + + public string Name { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/GradeDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/GradeDto.cs deleted file mode 100644 index 4876ec9cb992e209a764a46fc8e0de7107af6a28..0000000000000000000000000000000000000000 --- a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/GradeDto.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Text.Json.Serialization; - -namespace Tsi1.BusinessLayer.Dtos -{ - public class GradeDto - { - public int ActivityId { get; set; } - - public int UserId { get; set; } - - public decimal Value { get; set; } - } -} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/MyEvaluationInscriptionDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/MyEvaluationInscriptionDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..d4997da1ef84d6ed083d09541b9507a0a4d9d0b1 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/MyEvaluationInscriptionDto.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.BusinessLayer.Dtos +{ + public class MyEvaluationInscriptionDto + { + public string ActivityName { get; set; } + + public int EvaluationTypeId { get; set; } + + public string EvaluationType { get; set; } + + public decimal Grade { get; set; } + + public bool HasAttended { get; set; } + + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs index 2b12422eeae02f5d5cad8cd0cc9d6166d1d7a2cb..6812a7205963d518917cffee2c9c874f1a955986 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs @@ -69,5 +69,19 @@ namespace Tsi1.BusinessLayer.Helpers public const string ActivityDoesNotExist = "La actividad con id '{0}' no existe"; public const string GradeDoesNotExist = "La nota para la actividad con id '{0}' y usuario con id '{0}' no existe"; + + + public const string EvaluationTypeDoesNotExist = "El tipo de evaluación con id '{0}' no existe"; + public const string EvaluationDoesNotExist = "La evaluación con id '{0}' no existe"; + public const string EvaluationIsCompleted = "La evaluación con id '{0}' ha finalizado"; + public const string EvaluationInscriptionAlreadyExists = "El estudiante con id '{0}' ya se inscribió a la evaluación con id '{1}'"; + public const string EvaluationInscriptionDoesNotExists = "El estudiante con id '{0}' no esta inscripto en la evaluación con id '{1}'"; + public const string EvaluationInscriptionHasAttended = "El estudiante con id '{0}' ya realizó la evaluación con id '{1}'"; + public const string SubmissionDoesNotExists = "No existe ninguna tarea para el estudiante con id '{0}' en la evaluación con id '{1}'"; + public const string SubmissionAlreadyExists = "Ya existe una tarea para el estudiante con id '{0}' en la evaluación con id '{1}'"; + public const string InavalidUserSubmission = "La tarea con id '{0}' no pertenece al estudiante con id '{1}'"; + + public const string VideoConferenceIsNotEvaluation = "Una video conferencia no es una evaluación"; + } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/EvaluationTypes.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/EvaluationTypes.cs new file mode 100644 index 0000000000000000000000000000000000000000..446a98cf34b5995513303ee4ca537cc09d754b81 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/EvaluationTypes.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.BusinessLayer.Helpers +{ + public class EvaluationTypes + { + public const string Laboratory = nameof(Laboratory); + public const string Exam = nameof(Exam); + public const string MidTerm = nameof(MidTerm); + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs index d986e96bbc8775247c305c5b55bf1451053140a8..10ad515efecff6fb9cd77f40acb35e92c62aa0e9 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs @@ -61,7 +61,11 @@ namespace Tsi1.BusinessLayer.Helpers CreateMap<Activity, ActivityCreateDto>(); CreateMap<Activity, ActivityModifyDto>(); CreateMap<Activity, ActivityDto>(); - CreateMap<Grade, GradeDto>(); + CreateMap<EvaluationType, EvaluationTypeDto>(); + CreateMap<Evaluation, EvaluationCreateDto>(); + CreateMap<Evaluation, EvaluationModifyDto>(); + CreateMap<Evaluation, EvaluationDetailDto>(); + CreateMap<EvaluationInscription, EvaluationInscriptionDto>(); CreateMap<ForumCreateDto, Forum>(); CreateMap<ForumPreviewDto, Forum>(); @@ -109,7 +113,11 @@ namespace Tsi1.BusinessLayer.Helpers CreateMap<ActivityCreateDto, Activity>(); CreateMap<ActivityModifyDto, Activity>(); CreateMap<ActivityDto, Activity>(); - CreateMap<GradeDto, Grade>(); + CreateMap<EvaluationTypeDto, EvaluationType>(); + CreateMap<EvaluationCreateDto, Evaluation>(); + CreateMap<EvaluationModifyDto, Evaluation>().ForMember(x => x.Id, opt => opt.Ignore()); + CreateMap<EvaluationDetailDto, Evaluation>(); + CreateMap<EvaluationInscriptionDto, EvaluationInscription>(); } } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs index 43e11ae55cebab960701cd73efb5e620cd7c74a7..a8dfd19d3ab6d2ff3377d43fc7827d91e73eb1fd 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs @@ -15,10 +15,6 @@ namespace Tsi1.BusinessLayer.Interfaces Task<ServiceResult<int>> Modify(int activityId, ActivityModifyDto activityDto, int userId); Task<ServiceResult<int>> Delete(int activityId, int userId); - Task<ServiceResult<int>> ActivityValidation(int activityId, int userId); - Task<ServiceResult<GradeDto>> AddOrModifyGrade(GradeDto gradeDto, int userId); - Task<ServiceResult<int>> DeleteGrade(int myUserId, int activityId, int userId); - Task<ServiceResult<List<GradeDto>>> GetMyGrades(int activityId, int userId); - Task<ServiceResult<List<GradeDto>>> GetAllGrades(int activityId, int userId); + Task<ServiceResult<int>> ActivityValidation(int activityId, int userId); } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IEvaluationService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IEvaluationService.cs new file mode 100644 index 0000000000000000000000000000000000000000..c26aac04bed9b696d2ecddf95b4eed36c29bcdcd --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IEvaluationService.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Tsi1.BusinessLayer.Dtos; +using Tsi1.BusinessLayer.Helpers; + +namespace Tsi1.BusinessLayer.Interfaces +{ + public interface IEvaluationService + { + Task<ServiceResult<bool>> Registration(int evaluationId, int userId); + + Task<ServiceResult<bool>> CancelRegistration(int evaluationId, int userId); + + Task<ServiceResult<bool>> SubmitLaboratory(FileDto fileDto, int evaluationId, int userId); + + Task<ServiceResult<bool>> DeleteLaboratory(int submissionId, int userId); + + Task<ServiceResult<List<MyEvaluationInscriptionDto>>> GetMyEvaluationInscriptions(int userId, int courseId); + + Task<ServiceResult<List<EvaluationInscriptionDto>>> GetAllEvaluationInscriptions(int userId, int evaluationId); + + Task<ServiceResult<bool>> QualifyEvaluationInscription(EvaluationInscriptionModifyDto evaluationInscriptionDto, int userId); + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IEvaluationTypeService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IEvaluationTypeService.cs new file mode 100644 index 0000000000000000000000000000000000000000..55ac35724ef5331ea100cdbd5d2e832dfdfa2c75 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IEvaluationTypeService.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Tsi1.BusinessLayer.Dtos; +using Tsi1.BusinessLayer.Helpers; + +namespace Tsi1.BusinessLayer.Interfaces +{ + public interface IEvaluationTypeService + { + public Task<ServiceResult<EvaluationTypeDto>> GetById(int id); + + public Task<ServiceResult<List<EvaluationTypeDto>>> GetAll(string userType); + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs index fca3edd8d1cf94a4530a2fcb09f5b0d0dbd80832..ff629d1eaee7cfffdfc00419d14273957ef18405 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs @@ -179,38 +179,15 @@ namespace Tsi1.BusinessLayer.Services return result; } - var activity = _mapper.Map<Activity>(newActivity); - _context.Activities.Add(activity); - - await _context.SaveChangesAsync(); - - result.Data = activity.Id; - return result; - } - - public async Task<ServiceResult<int>> Modify(int activityId, ActivityModifyDto activityDto, int userId) - { - var result = new ServiceResult<int>(); - - var activity = await _context.Activities.FirstOrDefaultAsync(x => x.Id == activityId); - - if (activity == null) - { - result.HasError = true; - result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId)); - return result; - } - - var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId); - - if (userTypeValidation.HasError) + if (newActivity.IsVideoConference && newActivity.Evaluation != null) { result.HasError = true; - result.AddMessage(userTypeValidation.Message); + result.AddMessage(ErrorMessages.VideoConferenceIsNotEvaluation); return result; } - _mapper.Map(activityDto, activity); + var activity = _mapper.Map<Activity>(newActivity); + _context.Activities.Add(activity); await _context.SaveChangesAsync(); @@ -218,7 +195,7 @@ namespace Tsi1.BusinessLayer.Services return result; } - public async Task<ServiceResult<int>> Delete(int activityId, int userId) + public async Task<ServiceResult<int>> Modify(int activityId, ActivityModifyDto activityDto, int userId) { var result = new ServiceResult<int>(); @@ -240,105 +217,25 @@ namespace Tsi1.BusinessLayer.Services return result; } - _context.Activities.Remove(activity); - - await _context.SaveChangesAsync(); - - result.Data = activity.Id; - return result; - } - - public async Task<ServiceResult<GradeDto>> AddOrModifyGrade(GradeDto gradeDto, int userId) - { - var result = new ServiceResult<GradeDto>(); - - var activity = await _context.Activities.FirstOrDefaultAsync(x => x.Id == gradeDto.ActivityId); - - if (activity == null) + if (activityDto.IsVideoConference && activityDto.Evaluation != null) { result.HasError = true; - result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, gradeDto.ActivityId)); + result.AddMessage(ErrorMessages.VideoConferenceIsNotEvaluation); return result; } - var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId); - - if (userTypeValidation.HasError) - { - result.HasError = true; - result.AddMessage(userTypeValidation.Message); - return result; - } - - var userStudent = await _context.Users - .Include(x => x.Student) - .FirstOrDefaultAsync(x => x.Id == gradeDto.UserId); - - if (userStudent == null || userStudent.Student == null) - { - result.HasError = true; - result.AddMessage(string.Format(ErrorMessages.StudentDoesNotExist, gradeDto.UserId)); - return result; - } - - var userStudentValidation = await this.UserTypeValidation(activity.CourseId, userStudent.Id); - - if (userStudentValidation.HasError) - { - result.HasError = true; - result.AddMessage(userStudentValidation.Message); - return result; - } - - var grade = await _context.Grades - .FirstOrDefaultAsync(x => x.ActivityId == gradeDto.ActivityId && x.StudentId == userStudent.StudentId); - - if (grade == null) - { - grade = new Grade - { - ActivityId = gradeDto.ActivityId, - StudentId = (int)userStudent.StudentId - }; - - _context.Grades.Add(grade); - } - - grade.Value = gradeDto.Value; + _mapper.Map(activityDto, activity); - await _context.SaveChangesAsync(); - result.Data = gradeDto; + result.Data = activity.Id; return result; } - public async Task<ServiceResult<int>> DeleteGrade(int myUserId, int activityId, int userId) + public async Task<ServiceResult<int>> Delete(int activityId, int userId) { var result = new ServiceResult<int>(); - var userStudent = await _context.Users - .AsNoTracking() - .Include(x => x.Student) - .FirstOrDefaultAsync(x => x.Id == userId); - - if (userStudent == null || userStudent.Student == null) - { - result.HasError = true; - result.AddMessage(string.Format(ErrorMessages.StudentDoesNotExist, userStudent.Id)); - return result; - } - - var grade = await _context.Grades - .FirstOrDefaultAsync(x => x.ActivityId == activityId && x.StudentId == userStudent.StudentId); - - if (grade == null) - { - result.HasError = true; - result.AddMessage(string.Format(ErrorMessages.GradeDoesNotExist, activityId, userId)); - return result; - } - var activity = await _context.Activities.FirstOrDefaultAsync(x => x.Id == activityId); if (activity == null) @@ -357,99 +254,13 @@ namespace Tsi1.BusinessLayer.Services return result; } - _context.Grades.Remove(grade); - await _context.SaveChangesAsync(); - - return result; - } - - public async Task<ServiceResult<List<GradeDto>>> GetMyGrades(int activityId, int userId) - { - var result = new ServiceResult<List<GradeDto>>(); - - var activity = await _context.Activities.AsNoTracking().FirstOrDefaultAsync(x => x.Id == activityId); - - if (activity == null) - { - result.HasError = true; - result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId)); - return result; - } - - var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId); - - if (userTypeValidation.HasError) - { - result.HasError = true; - result.AddMessage(userTypeValidation.Message); - return result; - } - - var user = userTypeValidation.Data; + _context.Activities.Remove(activity); - var grades = await _context.Grades - .AsNoTracking() - .Where(x => x.ActivityId == activityId && x.StudentId == user.StudentId) - .ToListAsync(); + await _context.SaveChangesAsync(); - result.Data = _mapper.Map<List<GradeDto>>(grades); + result.Data = activity.Id; return result; } - public async Task<ServiceResult<List<GradeDto>>> GetAllGrades(int activityId, int userId) - { - var result = new ServiceResult<List<GradeDto>>(); - - var activity = await _context.Activities.AsNoTracking().FirstOrDefaultAsync(x => x.Id == activityId); - - if (activity == null) - { - result.HasError = true; - result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId)); - return result; - } - - var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId); - - if (userTypeValidation.HasError) - { - result.HasError = true; - result.AddMessage(userTypeValidation.Message); - return result; - } - - var user = userTypeValidation.Data; - - var grades = await _context.Grades - .AsNoTracking() - .Where(x => x.ActivityId == activityId) - .ToListAsync(); - - var studentIds = grades.Select(x => x.StudentId).ToList(); - - var users = await _context.Users - .AsNoTracking() - .Where(x => studentIds.Contains((int)x.StudentId)) - .ToListAsync(); - - var gradeDtos = new List<GradeDto>(); - - foreach (var grade in grades) - { - var userStudent = users.FirstOrDefault(x => x.StudentId == grade.StudentId); - - var gradeDto = new GradeDto - { - ActivityId = grade.ActivityId, - UserId = userStudent.Id, - Value = grade.Value - }; - - gradeDtos.Add(gradeDto); - } - - result.Data = gradeDtos; - return result; - } } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/EvaluationService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/EvaluationService.cs new file mode 100644 index 0000000000000000000000000000000000000000..9d20685d06a2bd51aef9f7dcc1826753ab0a56c0 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/EvaluationService.cs @@ -0,0 +1,420 @@ +using AutoMapper; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tsi1.BusinessLayer.Dtos; +using Tsi1.BusinessLayer.Helpers; +using Tsi1.BusinessLayer.Interfaces; +using Tsi1.DataLayer; +using Tsi1.DataLayer.Entities; + +namespace Tsi1.BusinessLayer.Services +{ + public class EvaluationService : IEvaluationService + { + private readonly Tsi1Context _context; + private readonly IMapper _mapper; + private readonly IFileService _fileService; + + public EvaluationService(Tsi1Context context, IMapper mapper, IFileService fileService) + { + _context = context; + _mapper = mapper; + _fileService = fileService; + } + + public async Task<ServiceResult<bool>> CancelRegistration(int evaluationId, int userId) + { + var result = new ServiceResult<bool>(); + + var validation = await this.StudentValidation(evaluationId, userId); + + if (validation.HasError) + { + result.HasError = true; + result.AddMessage(validation.Message); + return result; + } + + var studentId = validation.Data; + + var evaluationInscription = await _context.EvaluationInscriptions + .FirstOrDefaultAsync(x => x.EvaluationId == evaluationId && x.StudentId == studentId); + + if (evaluationInscription == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.EvaluationInscriptionDoesNotExists, studentId, evaluationId)); + return result; + } + + if (evaluationInscription.HasAttended) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.EvaluationInscriptionHasAttended, studentId, evaluationId)); + return result; + } + + _context.EvaluationInscriptions.Remove(evaluationInscription); + + await _context.SaveChangesAsync(); + + return result; + } + + public async Task<ServiceResult<bool>> DeleteLaboratory(int submissionId, int userId) + { + var result = new ServiceResult<bool>(); + + var user = await _context.Users + .AsNoTracking() + .Include(x => x.Student) + .FirstOrDefaultAsync(x => x.Id == userId); + + if (user == null || user.Student == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.UserDoesNotExist, userId)); + return result; + } + + var studentId = user.StudentId; + + var submission = await _context.Submissions.FirstOrDefaultAsync(x => x.Id == submissionId); + + if (submission == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.SubmissionDoesNotExists, submissionId)); + return result; + } + + if (submission.StudentId != studentId) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.InavalidUserSubmission, submissionId, studentId)); + return result; + } + + _context.Submissions.Remove(submission); + + await _context.SaveChangesAsync(); + + return result; + } + + public async Task<ServiceResult<List<EvaluationInscriptionDto>>> GetAllEvaluationInscriptions(int userId, int evaluationId) + { + var result = new ServiceResult<List<EvaluationInscriptionDto>>(); + + var validation = await this.ProfessorValidation(evaluationId, userId); + + if (validation.HasError) + { + result.HasError = true; + result.AddMessage(validation.Message); + return result; + } + + var evaluationInscriptions = await _context.EvaluationInscriptions + .Where(x => x.EvaluationId == evaluationId) + .ToListAsync(); + + result.Data = _mapper.Map<List<EvaluationInscriptionDto>>(evaluationInscriptions); + return result; + } + + public async Task<ServiceResult<List<MyEvaluationInscriptionDto>>> GetMyEvaluationInscriptions(int userId, int courseId) + { + var result = new ServiceResult<List<MyEvaluationInscriptionDto>>(); + + var course = await _context.Courses + .AsNoTracking() + .FirstOrDefaultAsync(x => x.Id == courseId); + + if (course == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.CourseDoesNotExist, courseId)); + return result; + } + + var user = await _context.Users + .AsNoTracking() + .Include(x => x.Student) + .FirstOrDefaultAsync(x => x.Id == userId); + + if (user == null || user.Student == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.UserDoesNotExist, userId)); + return result; + } + + var studentCourse = await _context.StudentCourses + .AsNoTracking() + .FirstOrDefaultAsync(x => x.StudentId == user.StudentId && x.CourseId == courseId); + + if (studentCourse == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.StudentCourseDoesNotExists, user.StudentId, courseId)); + return result; + } + + var evaluationInscriptions = await _context.EvaluationInscriptions + .AsNoTracking() + .Include(x => x.Evaluation) + .ThenInclude(x => x.Activity) + .Include(x => x.Evaluation) + .ThenInclude(x => x.EvaluationType) + .Where(x => x.StudentId == user.StudentId) + .ToListAsync(); + + var myEvaluationInscriptionDtos = new List<MyEvaluationInscriptionDto>(); + + foreach (var evaluationInscription in evaluationInscriptions) + { + var myEvaluationInscriptionDto = new MyEvaluationInscriptionDto + { + ActivityName = evaluationInscription.Evaluation.Activity.Name, + EvaluationTypeId = evaluationInscription.EvaluationId, + EvaluationType = evaluationInscription.Evaluation.EvaluationType.Name, + Grade = evaluationInscription.Grade, + HasAttended = evaluationInscription.HasAttended, + }; + + myEvaluationInscriptionDtos.Add(myEvaluationInscriptionDto); + } + + result.Data = myEvaluationInscriptionDtos; + return result; + } + + public async Task<ServiceResult<bool>> QualifyEvaluationInscription(EvaluationInscriptionModifyDto evaluationInscriptionDto, int userId) + { + var result = new ServiceResult<bool>(); + + var evaluationId = evaluationInscriptionDto.EvaluationId; + var studentId = evaluationInscriptionDto.StudentId; + + var validation = await this.ProfessorValidation(evaluationId, userId); + + if (validation.HasError) + { + result.HasError = true; + result.AddMessage(validation.Message); + return result; + } + + var evaluationInscription = await _context.EvaluationInscriptions + .FirstOrDefaultAsync(x => x.EvaluationId == evaluationId && x.StudentId == studentId); + + if (evaluationInscription == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.EvaluationInscriptionDoesNotExists, studentId, evaluationId)); + return result; + } + + evaluationInscription.Grade = evaluationInscriptionDto.Grade; + evaluationInscription.HasAttended = true; + + await _context.SaveChangesAsync(); + + return result; + } + + public async Task<ServiceResult<bool>> Registration(int evaluationId, int userId) + { + var result = new ServiceResult<bool>(); + + var validation = await this.StudentValidation(evaluationId, userId); + + if (validation.HasError) + { + result.HasError = true; + result.AddMessage(validation.Message); + return result; + } + + var studentId = validation.Data; + + var evaluationInscription = await _context.EvaluationInscriptions + .AsNoTracking() + .FirstOrDefaultAsync(x => x.EvaluationId == evaluationId && x.StudentId == studentId); + + if (evaluationInscription != null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.EvaluationInscriptionAlreadyExists, studentId, evaluationId)); + return result; + } + + var newEvaluationInscription = new EvaluationInscription + { + EvaluationId = evaluationId, + StudentId = studentId, + Grade = 0, + HasAttended = false, + }; + + _context.EvaluationInscriptions.Add(newEvaluationInscription); + + await _context.SaveChangesAsync(); + + return result; + } + + public async Task<ServiceResult<bool>> SubmitLaboratory(FileDto fileDto, int evaluationId, int userId) + { + var result = new ServiceResult<bool>(); + + var validation = await this.StudentValidation(evaluationId, userId); + + if (validation.HasError) + { + result.HasError = true; + result.AddMessage(validation.Message); + return result; + } + + var studentId = validation.Data; + + var evaluation = await _context.Evaluations + .Include(x => x.Submissions) + .FirstOrDefaultAsync(x => x.Id == evaluationId); + + var studentIds = evaluation.Submissions.Select(x => x.StudentId); + + if (studentIds.Contains(studentId)) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.SubmissionAlreadyExists, studentId, evaluationId)); + return result; + } + + if (!_fileService.ExistFile(fileDto.Path)) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.FileDoesNotExist, fileDto.Path)); + return result; + } + + var file = _mapper.Map<File>(fileDto); + + var newSubmission = new Submission + { + File = file, + StudentId = studentId, + Grade = 0, + IsCompleted = false, + }; + + evaluation.Submissions.Add(newSubmission); + + await _context.SaveChangesAsync(); + + return result; + } + + private async Task<ServiceResult<int>> StudentValidation(int evaluationId, int userId) + { + var result = new ServiceResult<int>(); + + var evaluation = await _context.Evaluations + .AsNoTracking() + .Include(x => x.Activity) + .FirstOrDefaultAsync(x => x.Id == evaluationId); + + if (evaluation == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.EvaluationDoesNotExist, evaluationId)); + return result; + } + + if (evaluation.IsCompleted) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.EvaluationIsCompleted, evaluationId)); + return result; + } + + var user = await _context.Users + .AsNoTracking() + .Include(x => x.Student) + .FirstOrDefaultAsync(x => x.Id == userId); + + if (user == null || user.Student == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.UserDoesNotExist, userId)); + return result; + } + + var activityCourseId = evaluation.Activity.CourseId; + + var studentCourse = await _context.StudentCourses + .AsNoTracking() + .FirstOrDefaultAsync(x => x.CourseId == activityCourseId && x.StudentId == user.StudentId); + + if (studentCourse == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.StudentCourseDoesNotExists, user.StudentId, activityCourseId)); + return result; + } + + result.Data = (int)user.StudentId; + return result; + } + + private async Task<ServiceResult<int>> ProfessorValidation(int evaluationId, int userId) + { + var result = new ServiceResult<int>(); + + var evaluation = await _context.Evaluations + .AsNoTracking() + .Include(x => x.Activity) + .FirstOrDefaultAsync(x => x.Id == evaluationId); + + if (evaluation == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.EvaluationDoesNotExist, evaluationId)); + } + + var user = await _context.Users + .AsNoTracking() + .Include(x => x.Professor) + .FirstOrDefaultAsync(x => x.Id == userId); + + if (user == null || user.Professor == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.ProfessorDoesNotExist, userId)); + return result; + } + + var activityCourseId = evaluation.Activity.CourseId; + + var professorCourse = await _context.ProfessorCourses + .AsNoTracking() + .FirstOrDefaultAsync(x => x.CourseId == activityCourseId && x.ProfessorId == user.ProfessorId); + + if (professorCourse == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.ProfessorCourseDoesNotExists, user.ProfessorId, activityCourseId)); + return result; + } + + result.Data = (int)user.ProfessorId; + return result; + } + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/EvaluationTypeService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/EvaluationTypeService.cs new file mode 100644 index 0000000000000000000000000000000000000000..d2ce280ffb68f1bdf6295dc05188251b61540e7d --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/EvaluationTypeService.cs @@ -0,0 +1,54 @@ +using AutoMapper; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Tsi1.BusinessLayer.Dtos; +using Tsi1.BusinessLayer.Helpers; +using Tsi1.BusinessLayer.Interfaces; +using Tsi1.DataLayer; + +namespace Tsi1.BusinessLayer.Services +{ + public class EvaluationTypeService : IEvaluationTypeService + { + private readonly Tsi1Context _context; + private readonly IMapper _mapper; + + public EvaluationTypeService(Tsi1Context context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task<ServiceResult<List<EvaluationTypeDto>>> GetAll(string userType) + { + var result = new ServiceResult<List<EvaluationTypeDto>>(); + + var evaluationTypes = await _context.EvaluationTypes.ToListAsync(); + + result.Data = _mapper.Map<List<EvaluationTypeDto>>(evaluationTypes); + + return result; + } + + public async Task<ServiceResult<EvaluationTypeDto>> GetById(int id) + { + var result = new ServiceResult<EvaluationTypeDto>(); + + var evaluationType = await _context.EvaluationTypes.FirstOrDefaultAsync(x => x.Id == id); + + if (evaluationType == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.EvaluationTypeDoesNotExist, id)); + return result; + } + + result.Data = _mapper.Map<EvaluationTypeDto>(evaluationType); + + return result; + } + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/FileService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/FileService.cs index 74c8fb4ff7b641e327843a8acfdcb1cd6e3bd99b..bd235875dd97fc443d8513d6b5639bcca27fd15c 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Services/FileService.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/FileService.cs @@ -19,13 +19,11 @@ namespace Tsi1.BusinessLayer.Services public class FileService : IFileService { private readonly Tsi1Context _context; - private readonly IMapper _mapper; private readonly string _path; - public FileService(Tsi1Context context, IMapper mapper, IHostingEnvironment hostingEnvironment) + public FileService(Tsi1Context context, IHostingEnvironment hostingEnvironment) { _context = context; - _mapper = mapper; _path = Path.Combine(hostingEnvironment.ContentRootPath, "StaticFiles"); } diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs index ca3a040ea1a657e30df7781e1c05307070495724..2dcbb58806597bc138c36e9289dfa625e1f08091 100644 --- a/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs @@ -9,7 +9,6 @@ namespace Tsi1.DataLayer.Entities public Activity() { Attendances = new HashSet<Attendance>(); - Grades = new HashSet<Grade>(); } public int Id { get; set; } @@ -18,12 +17,14 @@ namespace Tsi1.DataLayer.Entities public bool IsVideoConference { get; set; } + public int? EvaluationId { get; set; } + public int CourseId { get; set; } public Course Course { get; set; } - public ICollection<Attendance> Attendances { get; set; } + public Evaluation Evaluation { get; set; } - public ICollection<Grade> Grades { get; set; } + public ICollection<Attendance> Attendances { get; set; } } } diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Evaluation.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Evaluation.cs new file mode 100644 index 0000000000000000000000000000000000000000..d34c65c727a732b21bb00dadd1dc545d19a8a89a --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Evaluation.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.DataLayer.Entities +{ + public class Evaluation + { + public Evaluation() + { + EvaluationInscriptions = new HashSet<EvaluationInscription>(); + Submissions = new HashSet<Submission>(); + } + public int Id { get; set; } + + public int EvaluationTypeId { get; set; } + + public bool IsCompleted { get; set; } + + + public Activity Activity { get; set; } + + public EvaluationType EvaluationType { get; set; } + + public ICollection<EvaluationInscription> EvaluationInscriptions { get; set; } + + public ICollection<Submission> Submissions { get; set; } + + + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/EvaluationInscription.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/EvaluationInscription.cs new file mode 100644 index 0000000000000000000000000000000000000000..05fe24a173606a5f50da2a1383fb040f1b97f1b9 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/EvaluationInscription.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.DataLayer.Entities +{ + public class EvaluationInscription + { + public int EvaluationId { get; set; } + + public int StudentId { get; set; } + + public Evaluation Evaluation { get; set; } + + public Student Student { get; set; } + + public decimal Grade { get; set; } + + public bool HasAttended { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/EvaluationType.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/EvaluationType.cs new file mode 100644 index 0000000000000000000000000000000000000000..5cb4e72e318527f1a68ba34fc5d1d1d5cf1af190 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/EvaluationType.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.DataLayer.Entities +{ + public class EvaluationType + { + public int Id { get; set; } + + public string Name { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/File.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/File.cs index ea3324a77bd99ec20579f7aee468186c3c4bd643..96aa71c3052c36e423e9500e47cb1b3974aba62f 100644 --- a/Tsi1.Api/Tsi1.DataLayer/Entities/File.cs +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/File.cs @@ -10,6 +10,12 @@ namespace Tsi1.DataLayer.Entities public string Name { get; set; } public string Path { get; set; } + public bool IsSubmission { get; set; } + + public int? SubmissionId { get; set; } + + public Submission Submission { get; set; } + public SectionItem SectionItem { get; set; } } } diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Grade.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Grade.cs deleted file mode 100644 index c5c05e7a5c541434a33b3dd28131b76876711d34..0000000000000000000000000000000000000000 --- a/Tsi1.Api/Tsi1.DataLayer/Entities/Grade.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Tsi1.DataLayer.Entities -{ - public class Grade - { - public int ActivityId { get; set; } - - public int StudentId { get; set; } - - public decimal Value { get; set; } - - public DateTime Date { get; set; } - - public Student Student { get; set; } - - public Activity Activity { get; set; } - } -} diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs index 866c51651239ad1b38ce0ee23e6ba6002ccc24e6..82d423ab4a5533fd329ece9f79bc7d54c85de3f4 100644 --- a/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs @@ -9,7 +9,8 @@ namespace Tsi1.DataLayer.Entities public Student() { StudentCourses = new HashSet<StudentCourse>(); - Grades = new HashSet<Grade>(); + EvaluationInscriptions = new HashSet<EvaluationInscription>(); + Submissions = new HashSet<Submission>(); } public int Id { get; set; } @@ -24,6 +25,8 @@ namespace Tsi1.DataLayer.Entities public User User { get; set; } public ICollection<StudentCourse> StudentCourses { get; set; } - public ICollection<Grade> Grades { get; set; } + public ICollection<EvaluationInscription> EvaluationInscriptions { get; set; } + + public ICollection<Submission> Submissions { get; set; } } } diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Submission.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Submission.cs new file mode 100644 index 0000000000000000000000000000000000000000..add00c5960efa17310fde743c37469ab8d5c5b57 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Submission.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.DataLayer.Entities +{ + public class Submission + { + public int Id { get; set; } + + public int StudentId { get; set; } + + public int FileId { get; set; } + + public Student Student { get; set; } + + public File File { get; set; } + + public decimal Grade { get; set; } + + public bool IsCompleted { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ActivityConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ActivityConfiguration.cs index bb240989a2fd94ea21c55cf70fe94ffb6f144f78..b967312867456f0b32c3bfb68aaa05d9f4f2b3bb 100644 --- a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ActivityConfiguration.cs +++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ActivityConfiguration.cs @@ -20,6 +20,10 @@ namespace Tsi1.DataLayer.EntityConfiguration builder.HasOne(x => x.Course) .WithMany(x => x.Activities) .HasForeignKey(x => x.CourseId); + + builder.HasOne(x => x.Evaluation) + .WithOne(x => x.Activity) + .HasForeignKey<Activity>(x => x.EvaluationId); } } } diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/EvaluationConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/EvaluationConfiguration.cs new file mode 100644 index 0000000000000000000000000000000000000000..0cfb7fe714008cf57af8910182f36af9a1f303a6 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/EvaluationConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System; +using System.Collections.Generic; +using System.Text; +using Tsi1.DataLayer.Entities; + +namespace Tsi1.DataLayer.EntityConfiguration +{ + public class EvaluationConfiguration : IEntityTypeConfiguration<Evaluation> + { + public void Configure(EntityTypeBuilder<Evaluation> builder) + { + builder.HasKey(x => x.Id); + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/EvaluationInscriptionConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/EvaluationInscriptionConfiguration.cs new file mode 100644 index 0000000000000000000000000000000000000000..652d92bfe09e44f3601dc14f5d6d260b2af1a0e1 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/EvaluationInscriptionConfiguration.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System; +using System.Collections.Generic; +using System.Text; +using Tsi1.DataLayer.Entities; + +namespace Tsi1.DataLayer.EntityConfiguration +{ + public class EvaluationInscriptionConfiguration : IEntityTypeConfiguration<EvaluationInscription> + { + public void Configure(EntityTypeBuilder<EvaluationInscription> builder) + { + builder.HasKey(x => new { x.EvaluationId, x.StudentId }); + + builder.Property(x => x.Grade) + .IsRequired() + .HasColumnType("decimal(5,2)"); + + builder.HasOne(x => x.Evaluation) + .WithMany(x => x.EvaluationInscriptions) + .HasForeignKey(x => x.EvaluationId); + + builder.HasOne(x => x.Student) + .WithMany(x => x.EvaluationInscriptions) + .HasForeignKey(x => x.StudentId); + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/EvaluationTypeConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/EvaluationTypeConfiguration.cs new file mode 100644 index 0000000000000000000000000000000000000000..0406bf5260153bb65a851dcb884487a907813571 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/EvaluationTypeConfiguration.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System; +using System.Collections.Generic; +using System.Text; +using Tsi1.DataLayer.Entities; + +namespace Tsi1.DataLayer.EntityConfiguration +{ + public class EvaluationTypeConfiguration : IEntityTypeConfiguration<EvaluationType> + { + public void Configure(EntityTypeBuilder<EvaluationType> builder) + { + builder.HasKey(x => x.Id); + + builder.HasIndex(x => x.Name) + .IsUnique(); + + builder.Property(x => x.Name) + .IsRequired() + .HasColumnType("character varying(50)"); + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/FileConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/FileConfiguration.cs index ee21323fe9a845cfc5d780b24877022c0b09b2c2..b32e46347a601a9f975364e4cc6f2c8a7848bc2a 100644 --- a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/FileConfiguration.cs +++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/FileConfiguration.cs @@ -23,6 +23,10 @@ namespace Tsi1.DataLayer.EntityConfiguration builder.HasIndex(x => x.Path) .IsUnique(); + + builder.HasOne(x => x.Submission) + .WithOne(x => x.File) + .HasForeignKey<File>(x => x.SubmissionId); } } } diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/GradeConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/GradeConfiguration.cs deleted file mode 100644 index d8596a9ff6de422d94466eab94b3bcba0aa9736a..0000000000000000000000000000000000000000 --- a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/GradeConfiguration.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using System; -using System.Collections.Generic; -using System.Text; -using Tsi1.DataLayer.Entities; - -namespace Tsi1.DataLayer.EntityConfiguration -{ - public class GradeConfiguration : IEntityTypeConfiguration<Grade> - { - public void Configure(EntityTypeBuilder<Grade> builder) - { - builder.HasKey(x => new { x.ActivityId, x.StudentId}); - - builder.Property(x => x.Value) - .IsRequired() - .HasColumnType("NUMERIC(5,2)"); - - builder.HasOne(x => x.Activity) - .WithMany(x => x.Grades) - .HasForeignKey(x => x.ActivityId); - - builder.HasOne(x => x.Student) - .WithMany(x => x.Grades) - .HasForeignKey(x => x.StudentId); - } - } -} diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/SubmissionConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/SubmissionConfiguration.cs new file mode 100644 index 0000000000000000000000000000000000000000..7a4f33e1481a5eb383de12f5cd771f8177f31e2d --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/SubmissionConfiguration.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System; +using System.Collections.Generic; +using System.Text; +using Tsi1.DataLayer.Entities; + +namespace Tsi1.DataLayer.EntityConfiguration +{ + public class SubmissionConfiguration : IEntityTypeConfiguration<Submission> + { + public void Configure(EntityTypeBuilder<Submission> builder) + { + builder.HasKey(x => x.Id); + + builder.HasIndex(x => new { x.StudentId, x.FileId }) + .IsUnique(); + + builder.Property(x => x.Grade) + .IsRequired() + .HasColumnType("decimal(5,2)"); + + builder.HasOne(x => x.Student) + .WithMany(x => x.Submissions) + .HasForeignKey(x => x.StudentId); + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206230609_add-evaluation-entities.Designer.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206230609_add-evaluation-entities.Designer.cs new file mode 100644 index 0000000000000000000000000000000000000000..65e036dc3408ba71eb409020c86dc09358a316b5 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206230609_add-evaluation-entities.Designer.cs @@ -0,0 +1,1095 @@ +// <auto-generated /> +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Tsi1.DataLayer; + +namespace Tsi1.DataLayer.Migrations +{ + [DbContext(typeof(Tsi1Context))] + [Migration("20201206230609_add-evaluation-entities")] + partial class addevaluationentities + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.1.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.Property<int?>("EvaluationId") + .HasColumnType("integer"); + + b.Property<bool>("IsVideoConference") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("EvaluationId"); + + b.ToTable("Activities"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.AnswerOption", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AnswerOptions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ActivityId"); + + b.HasIndex("UserId"); + + b.ToTable("Attendances"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("CourseId") + .HasColumnType("integer"); + + b.Property<bool>("IsGlobal") + .HasColumnType("boolean"); + + b.Property<int?>("TenantId") + .HasColumnType("integer"); + + b.Property<string>("Text") + .IsRequired() + .HasColumnType("character varying(1000)"); + + b.Property<DateTime>("ValidUntil") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("TenantId"); + + b.HasIndex("ValidUntil"); + + b.ToTable("Communications"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b => + { + b.Property<string>("ConnectionId") + .HasColumnType("text"); + + b.Property<string>("GroupName") + .HasColumnType("text"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("ConnectionId"); + + b.HasIndex("GroupName"); + + b.ToTable("Connections"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsTemplate") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("Name", "TenantId") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Evaluation", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("EvaluationTypeId") + .HasColumnType("integer"); + + b.Property<bool>("IsCompleted") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationTypeId"); + + b.ToTable("Evaluations"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationInscription", b => + { + b.Property<int>("EvaluationId") + .HasColumnType("integer"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<decimal>("Grade") + .HasColumnType("decimal(5,2)"); + + b.Property<bool>("HasAttended") + .HasColumnType("boolean"); + + b.HasKey("EvaluationId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("EvaluationInscriptions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("EvaluationTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsSubmission") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<string>("Path") + .IsRequired() + .HasColumnType("character varying(1000)"); + + b.Property<int?>("SubmissionId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.HasIndex("SubmissionId") + .IsUnique(); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Forum", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Forums"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b => + { + b.Property<int>("ForumId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("ForumId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ForumUsers"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<decimal>("Value") + .HasColumnType("NUMERIC(5,2)"); + + b.HasKey("ActivityId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("Grades"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Group", b => + { + b.Property<string>("Name") + .HasColumnType("text"); + + b.HasKey("Name"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("ForumId") + .HasColumnType("integer"); + + b.Property<string>("Title") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("ForumId", "Title") + .IsUnique(); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Content") + .IsRequired() + .HasColumnType("character varying(10485760)"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("PostId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostMessages"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("IdentityCard") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("IdentityCard", "TenantId") + .IsUnique(); + + b.ToTable("Professors"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b => + { + b.Property<int>("ProfessorId") + .HasColumnType("integer"); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.HasKey("ProfessorId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("ProfessorCourses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int>("Order") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.ToTable("Sections"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("FileId") + .HasColumnType("integer"); + + b.Property<int?>("ForumId") + .HasColumnType("integer"); + + b.Property<int>("Order") + .HasColumnType("integer"); + + b.Property<int>("SectionId") + .HasColumnType("integer"); + + b.Property<int>("SectionItemTypeId") + .HasColumnType("integer"); + + b.Property<int?>("SurveyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("FileId") + .IsUnique(); + + b.HasIndex("ForumId") + .IsUnique(); + + b.HasIndex("SectionId"); + + b.HasIndex("SectionItemTypeId"); + + b.HasIndex("SurveyId") + .IsUnique(); + + b.ToTable("SectionItems"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItemType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("SectionItemTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("Age") + .HasColumnType("integer"); + + b.Property<string>("IdentityCard") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("IdentityCard", "TenantId") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b => + { + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.HasKey("StudentId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("StudentCourses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Submission", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("EvaluationId") + .HasColumnType("integer"); + + b.Property<int>("FileId") + .HasColumnType("integer"); + + b.Property<decimal>("Grade") + .HasColumnType("decimal(5,2)"); + + b.Property<bool>("IsCompleted") + .HasColumnType("boolean"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationId"); + + b.HasIndex("StudentId", "FileId") + .IsUnique(); + + b.ToTable("Submissions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsGlobal") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int?>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.HasIndex("TenantId"); + + b.ToTable("Surveys"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("AnswerOptionId") + .HasColumnType("integer"); + + b.Property<int>("SurveyQuestionId") + .HasColumnType("integer"); + + b.Property<int>("SurveyResponseId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AnswerOptionId"); + + b.HasIndex("SurveyQuestionId"); + + b.HasIndex("SurveyResponseId"); + + b.ToTable("SurveyAnswers"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Question") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int>("SurveyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.ToTable("SurveyQuestions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("SurveyId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.HasIndex("UserId"); + + b.ToTable("SurveyResponses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Tenant", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Email") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("FirstName") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("LastName") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("Password") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int?>("ProfessorId") + .HasColumnType("integer"); + + b.Property<int?>("StudentId") + .HasColumnType("integer"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.Property<int>("UserTypeId") + .HasColumnType("integer"); + + b.Property<string>("Username") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProfessorId") + .IsUnique(); + + b.HasIndex("StudentId") + .IsUnique(); + + b.HasIndex("TenantId"); + + b.HasIndex("UserTypeId"); + + b.HasIndex("Username", "TenantId") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.UserType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("UserTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Activities") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", "Evaluation") + .WithMany() + .HasForeignKey("EvaluationId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity") + .WithMany("Attendances") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("Attendances") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Communications") + .HasForeignKey("CourseId"); + + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Communications") + .HasForeignKey("TenantId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Group", "Group") + .WithMany("Connections") + .HasForeignKey("GroupName"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Courses") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Evaluation", b => + { + b.HasOne("Tsi1.DataLayer.Entities.EvaluationType", "EvaluationType") + .WithMany() + .HasForeignKey("EvaluationTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationInscription", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", "Evaluation") + .WithMany("EvaluationInscriptions") + .HasForeignKey("EvaluationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("EvaluationInscriptions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Submission", "Submission") + .WithOne("File") + .HasForeignKey("Tsi1.DataLayer.Entities.File", "SubmissionId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithMany("ForumUsers") + .HasForeignKey("ForumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("ForumUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity") + .WithMany("Grades") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("Grades") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithMany("Posts") + .HasForeignKey("ForumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("Posts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Post", "Post") + .WithMany("PostMessages") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("PostMessages") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Professors") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("ProfessorCourses") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor") + .WithMany("ProfessorCourses") + .HasForeignKey("ProfessorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Sections") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b => + { + b.HasOne("Tsi1.DataLayer.Entities.File", "File") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "FileId"); + + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "ForumId"); + + b.HasOne("Tsi1.DataLayer.Entities.Section", "Section") + .WithMany("SectionItems") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SectionItemType", "SectionItemType") + .WithMany("SectionItems") + .HasForeignKey("SectionItemTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "SurveyId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Students") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("StudentCourses") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("StudentCourses") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Submission", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", null) + .WithMany("Submissions") + .HasForeignKey("EvaluationId"); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Surveys") + .HasForeignKey("TenantId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b => + { + b.HasOne("Tsi1.DataLayer.Entities.AnswerOption", "AnswerOption") + .WithMany("SurveyAnswers") + .HasForeignKey("AnswerOptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SurveyQuestion", "SurveyQuestion") + .WithMany("SurveyAnswers") + .HasForeignKey("SurveyQuestionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SurveyResponse", "SurveyResponse") + .WithMany("SurveyAnswers") + .HasForeignKey("SurveyResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithMany("SurveyQuestions") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithMany("SurveyResponses") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("SurveyResponses") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor") + .WithOne("User") + .HasForeignKey("Tsi1.DataLayer.Entities.User", "ProfessorId"); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithOne("User") + .HasForeignKey("Tsi1.DataLayer.Entities.User", "StudentId"); + + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Users") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.UserType", "UserType") + .WithMany() + .HasForeignKey("UserTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206230609_add-evaluation-entities.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206230609_add-evaluation-entities.cs new file mode 100644 index 0000000000000000000000000000000000000000..1e8a648d6ccea12d939c2f7e114c7634bd91a72c --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206230609_add-evaluation-entities.cs @@ -0,0 +1,212 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Tsi1.DataLayer.Migrations +{ + public partial class addevaluationentities : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn<bool>( + name: "IsSubmission", + table: "Files", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn<int>( + name: "SubmissionId", + table: "Files", + nullable: true); + + migrationBuilder.AddColumn<int>( + name: "EvaluationId", + table: "Activities", + nullable: true); + + migrationBuilder.CreateTable( + name: "EvaluationTypes", + columns: table => new + { + Id = table.Column<int>(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column<string>(type: "character varying(50)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EvaluationTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Evaluations", + columns: table => new + { + Id = table.Column<int>(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + EvaluationTypeId = table.Column<int>(nullable: false), + IsCompleted = table.Column<bool>(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Evaluations", x => x.Id); + table.ForeignKey( + name: "FK_Evaluations_EvaluationTypes_EvaluationTypeId", + column: x => x.EvaluationTypeId, + principalTable: "EvaluationTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "EvaluationInscriptions", + columns: table => new + { + EvaluationId = table.Column<int>(nullable: false), + StudentId = table.Column<int>(nullable: false), + Grade = table.Column<decimal>(type: "decimal(5,2)", nullable: false), + HasAttended = table.Column<bool>(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EvaluationInscriptions", x => new { x.EvaluationId, x.StudentId }); + table.ForeignKey( + name: "FK_EvaluationInscriptions_Evaluations_EvaluationId", + column: x => x.EvaluationId, + principalTable: "Evaluations", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EvaluationInscriptions_Students_StudentId", + column: x => x.StudentId, + principalTable: "Students", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Submissions", + columns: table => new + { + Id = table.Column<int>(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + StudentId = table.Column<int>(nullable: false), + FileId = table.Column<int>(nullable: false), + Grade = table.Column<decimal>(type: "decimal(5,2)", nullable: false), + IsCompleted = table.Column<bool>(nullable: false), + EvaluationId = table.Column<int>(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Submissions", x => x.Id); + table.ForeignKey( + name: "FK_Submissions_Evaluations_EvaluationId", + column: x => x.EvaluationId, + principalTable: "Evaluations", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Submissions_Students_StudentId", + column: x => x.StudentId, + principalTable: "Students", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Files_SubmissionId", + table: "Files", + column: "SubmissionId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Activities_EvaluationId", + table: "Activities", + column: "EvaluationId"); + + migrationBuilder.CreateIndex( + name: "IX_EvaluationInscriptions_StudentId", + table: "EvaluationInscriptions", + column: "StudentId"); + + migrationBuilder.CreateIndex( + name: "IX_Evaluations_EvaluationTypeId", + table: "Evaluations", + column: "EvaluationTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_EvaluationTypes_Name", + table: "EvaluationTypes", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Submissions_EvaluationId", + table: "Submissions", + column: "EvaluationId"); + + migrationBuilder.CreateIndex( + name: "IX_Submissions_StudentId_FileId", + table: "Submissions", + columns: new[] { "StudentId", "FileId" }, + unique: true); + + migrationBuilder.AddForeignKey( + name: "FK_Activities_Evaluations_EvaluationId", + table: "Activities", + column: "EvaluationId", + principalTable: "Evaluations", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Files_Submissions_SubmissionId", + table: "Files", + column: "SubmissionId", + principalTable: "Submissions", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Activities_Evaluations_EvaluationId", + table: "Activities"); + + migrationBuilder.DropForeignKey( + name: "FK_Files_Submissions_SubmissionId", + table: "Files"); + + migrationBuilder.DropTable( + name: "EvaluationInscriptions"); + + migrationBuilder.DropTable( + name: "Submissions"); + + migrationBuilder.DropTable( + name: "Evaluations"); + + migrationBuilder.DropTable( + name: "EvaluationTypes"); + + migrationBuilder.DropIndex( + name: "IX_Files_SubmissionId", + table: "Files"); + + migrationBuilder.DropIndex( + name: "IX_Activities_EvaluationId", + table: "Activities"); + + migrationBuilder.DropColumn( + name: "IsSubmission", + table: "Files"); + + migrationBuilder.DropColumn( + name: "SubmissionId", + table: "Files"); + + migrationBuilder.DropColumn( + name: "EvaluationId", + table: "Activities"); + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231432_add-relation-between-activity-and-evaluation.Designer.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231432_add-relation-between-activity-and-evaluation.Designer.cs new file mode 100644 index 0000000000000000000000000000000000000000..cd348cbb54ee9da717bdf044b4e4687343ca5d48 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231432_add-relation-between-activity-and-evaluation.Designer.cs @@ -0,0 +1,1099 @@ +// <auto-generated /> +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Tsi1.DataLayer; + +namespace Tsi1.DataLayer.Migrations +{ + [DbContext(typeof(Tsi1Context))] + [Migration("20201206231432_add-relation-between-activity-and-evaluation")] + partial class addrelationbetweenactivityandevaluation + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.1.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.Property<int?>("EvaluationId") + .HasColumnType("integer"); + + b.Property<bool>("IsVideoConference") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("EvaluationId") + .IsUnique(); + + b.ToTable("Activities"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.AnswerOption", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AnswerOptions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ActivityId"); + + b.HasIndex("UserId"); + + b.ToTable("Attendances"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("CourseId") + .HasColumnType("integer"); + + b.Property<bool>("IsGlobal") + .HasColumnType("boolean"); + + b.Property<int?>("TenantId") + .HasColumnType("integer"); + + b.Property<string>("Text") + .IsRequired() + .HasColumnType("character varying(1000)"); + + b.Property<DateTime>("ValidUntil") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("TenantId"); + + b.HasIndex("ValidUntil"); + + b.ToTable("Communications"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b => + { + b.Property<string>("ConnectionId") + .HasColumnType("text"); + + b.Property<string>("GroupName") + .HasColumnType("text"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("ConnectionId"); + + b.HasIndex("GroupName"); + + b.ToTable("Connections"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsTemplate") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("Name", "TenantId") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Evaluation", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<int>("EvaluationTypeId") + .HasColumnType("integer"); + + b.Property<bool>("IsCompleted") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationTypeId"); + + b.ToTable("Evaluations"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationInscription", b => + { + b.Property<int>("EvaluationId") + .HasColumnType("integer"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<decimal>("Grade") + .HasColumnType("decimal(5,2)"); + + b.Property<bool>("HasAttended") + .HasColumnType("boolean"); + + b.HasKey("EvaluationId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("EvaluationInscriptions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("EvaluationTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsSubmission") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<string>("Path") + .IsRequired() + .HasColumnType("character varying(1000)"); + + b.Property<int?>("SubmissionId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.HasIndex("SubmissionId") + .IsUnique(); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Forum", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Forums"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b => + { + b.Property<int>("ForumId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("ForumId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ForumUsers"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<decimal>("Value") + .HasColumnType("NUMERIC(5,2)"); + + b.HasKey("ActivityId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("Grades"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Group", b => + { + b.Property<string>("Name") + .HasColumnType("text"); + + b.HasKey("Name"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("ForumId") + .HasColumnType("integer"); + + b.Property<string>("Title") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("ForumId", "Title") + .IsUnique(); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Content") + .IsRequired() + .HasColumnType("character varying(10485760)"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("PostId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostMessages"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("IdentityCard") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("IdentityCard", "TenantId") + .IsUnique(); + + b.ToTable("Professors"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b => + { + b.Property<int>("ProfessorId") + .HasColumnType("integer"); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.HasKey("ProfessorId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("ProfessorCourses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int>("Order") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.ToTable("Sections"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("FileId") + .HasColumnType("integer"); + + b.Property<int?>("ForumId") + .HasColumnType("integer"); + + b.Property<int>("Order") + .HasColumnType("integer"); + + b.Property<int>("SectionId") + .HasColumnType("integer"); + + b.Property<int>("SectionItemTypeId") + .HasColumnType("integer"); + + b.Property<int?>("SurveyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("FileId") + .IsUnique(); + + b.HasIndex("ForumId") + .IsUnique(); + + b.HasIndex("SectionId"); + + b.HasIndex("SectionItemTypeId"); + + b.HasIndex("SurveyId") + .IsUnique(); + + b.ToTable("SectionItems"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItemType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("SectionItemTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("Age") + .HasColumnType("integer"); + + b.Property<string>("IdentityCard") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("IdentityCard", "TenantId") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b => + { + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.HasKey("StudentId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("StudentCourses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Submission", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("EvaluationId") + .HasColumnType("integer"); + + b.Property<int>("FileId") + .HasColumnType("integer"); + + b.Property<decimal>("Grade") + .HasColumnType("decimal(5,2)"); + + b.Property<bool>("IsCompleted") + .HasColumnType("boolean"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationId"); + + b.HasIndex("StudentId", "FileId") + .IsUnique(); + + b.ToTable("Submissions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsGlobal") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int?>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.HasIndex("TenantId"); + + b.ToTable("Surveys"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("AnswerOptionId") + .HasColumnType("integer"); + + b.Property<int>("SurveyQuestionId") + .HasColumnType("integer"); + + b.Property<int>("SurveyResponseId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AnswerOptionId"); + + b.HasIndex("SurveyQuestionId"); + + b.HasIndex("SurveyResponseId"); + + b.ToTable("SurveyAnswers"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Question") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int>("SurveyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.ToTable("SurveyQuestions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("SurveyId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.HasIndex("UserId"); + + b.ToTable("SurveyResponses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Tenant", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Email") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("FirstName") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("LastName") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("Password") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int?>("ProfessorId") + .HasColumnType("integer"); + + b.Property<int?>("StudentId") + .HasColumnType("integer"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.Property<int>("UserTypeId") + .HasColumnType("integer"); + + b.Property<string>("Username") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProfessorId") + .IsUnique(); + + b.HasIndex("StudentId") + .IsUnique(); + + b.HasIndex("TenantId"); + + b.HasIndex("UserTypeId"); + + b.HasIndex("Username", "TenantId") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.UserType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("UserTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Activities") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", "Evaluation") + .WithOne("Activity") + .HasForeignKey("Tsi1.DataLayer.Entities.Activity", "EvaluationId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity") + .WithMany("Attendances") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("Attendances") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Communications") + .HasForeignKey("CourseId"); + + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Communications") + .HasForeignKey("TenantId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Group", "Group") + .WithMany("Connections") + .HasForeignKey("GroupName"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Courses") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Evaluation", b => + { + b.HasOne("Tsi1.DataLayer.Entities.EvaluationType", "EvaluationType") + .WithMany() + .HasForeignKey("EvaluationTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationInscription", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", "Evaluation") + .WithMany("EvaluationInscriptions") + .HasForeignKey("EvaluationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("EvaluationInscriptions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Submission", "Submission") + .WithOne("File") + .HasForeignKey("Tsi1.DataLayer.Entities.File", "SubmissionId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithMany("ForumUsers") + .HasForeignKey("ForumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("ForumUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity") + .WithMany("Grades") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("Grades") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithMany("Posts") + .HasForeignKey("ForumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("Posts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Post", "Post") + .WithMany("PostMessages") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("PostMessages") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Professors") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("ProfessorCourses") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor") + .WithMany("ProfessorCourses") + .HasForeignKey("ProfessorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Sections") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b => + { + b.HasOne("Tsi1.DataLayer.Entities.File", "File") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "FileId"); + + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "ForumId"); + + b.HasOne("Tsi1.DataLayer.Entities.Section", "Section") + .WithMany("SectionItems") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SectionItemType", "SectionItemType") + .WithMany("SectionItems") + .HasForeignKey("SectionItemTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "SurveyId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Students") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("StudentCourses") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("StudentCourses") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Submission", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", null) + .WithMany("Submissions") + .HasForeignKey("EvaluationId"); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Surveys") + .HasForeignKey("TenantId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b => + { + b.HasOne("Tsi1.DataLayer.Entities.AnswerOption", "AnswerOption") + .WithMany("SurveyAnswers") + .HasForeignKey("AnswerOptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SurveyQuestion", "SurveyQuestion") + .WithMany("SurveyAnswers") + .HasForeignKey("SurveyQuestionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SurveyResponse", "SurveyResponse") + .WithMany("SurveyAnswers") + .HasForeignKey("SurveyResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithMany("SurveyQuestions") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithMany("SurveyResponses") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("SurveyResponses") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor") + .WithOne("User") + .HasForeignKey("Tsi1.DataLayer.Entities.User", "ProfessorId"); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithOne("User") + .HasForeignKey("Tsi1.DataLayer.Entities.User", "StudentId"); + + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Users") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.UserType", "UserType") + .WithMany() + .HasForeignKey("UserTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231432_add-relation-between-activity-and-evaluation.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231432_add-relation-between-activity-and-evaluation.cs new file mode 100644 index 0000000000000000000000000000000000000000..a43fe7c17011122fc3dbc919620da646de908bbf --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231432_add-relation-between-activity-and-evaluation.cs @@ -0,0 +1,42 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Tsi1.DataLayer.Migrations +{ + public partial class addrelationbetweenactivityandevaluation : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Activities_EvaluationId", + table: "Activities"); + + migrationBuilder.AddColumn<int>( + name: "ActivityId", + table: "Evaluations", + nullable: false, + defaultValue: 0); + + migrationBuilder.CreateIndex( + name: "IX_Activities_EvaluationId", + table: "Activities", + column: "EvaluationId", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Activities_EvaluationId", + table: "Activities"); + + migrationBuilder.DropColumn( + name: "ActivityId", + table: "Evaluations"); + + migrationBuilder.CreateIndex( + name: "IX_Activities_EvaluationId", + table: "Activities", + column: "EvaluationId"); + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231716_fix-evaluation.Designer.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231716_fix-evaluation.Designer.cs new file mode 100644 index 0000000000000000000000000000000000000000..a82090a61d055bdf6fe6c00879b0cba1d9076b18 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231716_fix-evaluation.Designer.cs @@ -0,0 +1,1096 @@ +// <auto-generated /> +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Tsi1.DataLayer; + +namespace Tsi1.DataLayer.Migrations +{ + [DbContext(typeof(Tsi1Context))] + [Migration("20201206231716_fix-evaluation")] + partial class fixevaluation + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.1.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.Property<int?>("EvaluationId") + .HasColumnType("integer"); + + b.Property<bool>("IsVideoConference") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("EvaluationId") + .IsUnique(); + + b.ToTable("Activities"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.AnswerOption", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AnswerOptions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ActivityId"); + + b.HasIndex("UserId"); + + b.ToTable("Attendances"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("CourseId") + .HasColumnType("integer"); + + b.Property<bool>("IsGlobal") + .HasColumnType("boolean"); + + b.Property<int?>("TenantId") + .HasColumnType("integer"); + + b.Property<string>("Text") + .IsRequired() + .HasColumnType("character varying(1000)"); + + b.Property<DateTime>("ValidUntil") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("TenantId"); + + b.HasIndex("ValidUntil"); + + b.ToTable("Communications"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b => + { + b.Property<string>("ConnectionId") + .HasColumnType("text"); + + b.Property<string>("GroupName") + .HasColumnType("text"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("ConnectionId"); + + b.HasIndex("GroupName"); + + b.ToTable("Connections"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsTemplate") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("Name", "TenantId") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Evaluation", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("EvaluationTypeId") + .HasColumnType("integer"); + + b.Property<bool>("IsCompleted") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationTypeId"); + + b.ToTable("Evaluations"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationInscription", b => + { + b.Property<int>("EvaluationId") + .HasColumnType("integer"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<decimal>("Grade") + .HasColumnType("decimal(5,2)"); + + b.Property<bool>("HasAttended") + .HasColumnType("boolean"); + + b.HasKey("EvaluationId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("EvaluationInscriptions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("EvaluationTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsSubmission") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<string>("Path") + .IsRequired() + .HasColumnType("character varying(1000)"); + + b.Property<int?>("SubmissionId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.HasIndex("SubmissionId") + .IsUnique(); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Forum", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Forums"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b => + { + b.Property<int>("ForumId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("ForumId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ForumUsers"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<decimal>("Value") + .HasColumnType("NUMERIC(5,2)"); + + b.HasKey("ActivityId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("Grades"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Group", b => + { + b.Property<string>("Name") + .HasColumnType("text"); + + b.HasKey("Name"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("ForumId") + .HasColumnType("integer"); + + b.Property<string>("Title") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("ForumId", "Title") + .IsUnique(); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Content") + .IsRequired() + .HasColumnType("character varying(10485760)"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("PostId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostMessages"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("IdentityCard") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("IdentityCard", "TenantId") + .IsUnique(); + + b.ToTable("Professors"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b => + { + b.Property<int>("ProfessorId") + .HasColumnType("integer"); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.HasKey("ProfessorId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("ProfessorCourses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int>("Order") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.ToTable("Sections"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("FileId") + .HasColumnType("integer"); + + b.Property<int?>("ForumId") + .HasColumnType("integer"); + + b.Property<int>("Order") + .HasColumnType("integer"); + + b.Property<int>("SectionId") + .HasColumnType("integer"); + + b.Property<int>("SectionItemTypeId") + .HasColumnType("integer"); + + b.Property<int?>("SurveyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("FileId") + .IsUnique(); + + b.HasIndex("ForumId") + .IsUnique(); + + b.HasIndex("SectionId"); + + b.HasIndex("SectionItemTypeId"); + + b.HasIndex("SurveyId") + .IsUnique(); + + b.ToTable("SectionItems"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItemType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("SectionItemTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("Age") + .HasColumnType("integer"); + + b.Property<string>("IdentityCard") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("IdentityCard", "TenantId") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b => + { + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.HasKey("StudentId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("StudentCourses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Submission", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("EvaluationId") + .HasColumnType("integer"); + + b.Property<int>("FileId") + .HasColumnType("integer"); + + b.Property<decimal>("Grade") + .HasColumnType("decimal(5,2)"); + + b.Property<bool>("IsCompleted") + .HasColumnType("boolean"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationId"); + + b.HasIndex("StudentId", "FileId") + .IsUnique(); + + b.ToTable("Submissions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsGlobal") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int?>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.HasIndex("TenantId"); + + b.ToTable("Surveys"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("AnswerOptionId") + .HasColumnType("integer"); + + b.Property<int>("SurveyQuestionId") + .HasColumnType("integer"); + + b.Property<int>("SurveyResponseId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AnswerOptionId"); + + b.HasIndex("SurveyQuestionId"); + + b.HasIndex("SurveyResponseId"); + + b.ToTable("SurveyAnswers"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Question") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int>("SurveyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.ToTable("SurveyQuestions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("SurveyId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.HasIndex("UserId"); + + b.ToTable("SurveyResponses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Tenant", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Email") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("FirstName") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("LastName") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("Password") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int?>("ProfessorId") + .HasColumnType("integer"); + + b.Property<int?>("StudentId") + .HasColumnType("integer"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.Property<int>("UserTypeId") + .HasColumnType("integer"); + + b.Property<string>("Username") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProfessorId") + .IsUnique(); + + b.HasIndex("StudentId") + .IsUnique(); + + b.HasIndex("TenantId"); + + b.HasIndex("UserTypeId"); + + b.HasIndex("Username", "TenantId") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.UserType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("UserTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Activities") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", "Evaluation") + .WithOne("Activity") + .HasForeignKey("Tsi1.DataLayer.Entities.Activity", "EvaluationId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity") + .WithMany("Attendances") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("Attendances") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Communications") + .HasForeignKey("CourseId"); + + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Communications") + .HasForeignKey("TenantId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Group", "Group") + .WithMany("Connections") + .HasForeignKey("GroupName"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Courses") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Evaluation", b => + { + b.HasOne("Tsi1.DataLayer.Entities.EvaluationType", "EvaluationType") + .WithMany() + .HasForeignKey("EvaluationTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationInscription", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", "Evaluation") + .WithMany("EvaluationInscriptions") + .HasForeignKey("EvaluationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("EvaluationInscriptions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Submission", "Submission") + .WithOne("File") + .HasForeignKey("Tsi1.DataLayer.Entities.File", "SubmissionId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithMany("ForumUsers") + .HasForeignKey("ForumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("ForumUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity") + .WithMany("Grades") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("Grades") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithMany("Posts") + .HasForeignKey("ForumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("Posts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Post", "Post") + .WithMany("PostMessages") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("PostMessages") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Professors") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("ProfessorCourses") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor") + .WithMany("ProfessorCourses") + .HasForeignKey("ProfessorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Sections") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b => + { + b.HasOne("Tsi1.DataLayer.Entities.File", "File") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "FileId"); + + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "ForumId"); + + b.HasOne("Tsi1.DataLayer.Entities.Section", "Section") + .WithMany("SectionItems") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SectionItemType", "SectionItemType") + .WithMany("SectionItems") + .HasForeignKey("SectionItemTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "SurveyId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Students") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("StudentCourses") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("StudentCourses") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Submission", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", null) + .WithMany("Submissions") + .HasForeignKey("EvaluationId"); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Surveys") + .HasForeignKey("TenantId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b => + { + b.HasOne("Tsi1.DataLayer.Entities.AnswerOption", "AnswerOption") + .WithMany("SurveyAnswers") + .HasForeignKey("AnswerOptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SurveyQuestion", "SurveyQuestion") + .WithMany("SurveyAnswers") + .HasForeignKey("SurveyQuestionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SurveyResponse", "SurveyResponse") + .WithMany("SurveyAnswers") + .HasForeignKey("SurveyResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithMany("SurveyQuestions") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithMany("SurveyResponses") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("SurveyResponses") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor") + .WithOne("User") + .HasForeignKey("Tsi1.DataLayer.Entities.User", "ProfessorId"); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithOne("User") + .HasForeignKey("Tsi1.DataLayer.Entities.User", "StudentId"); + + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Users") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.UserType", "UserType") + .WithMany() + .HasForeignKey("UserTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231716_fix-evaluation.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231716_fix-evaluation.cs new file mode 100644 index 0000000000000000000000000000000000000000..91e8df6e6e532ca7e13ac424a0881b297dba7310 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201206231716_fix-evaluation.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Tsi1.DataLayer.Migrations +{ + public partial class fixevaluation : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ActivityId", + table: "Evaluations"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn<int>( + name: "ActivityId", + table: "Evaluations", + type: "integer", + nullable: false, + defaultValue: 0); + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs index 98c1fb3cb825c778529acca3b09b9c2c149f3ac6..2ccddabbbeb4f064563eef1292bed4c8129ab74f 100644 --- a/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs @@ -29,6 +29,9 @@ namespace Tsi1.DataLayer.Migrations b.Property<int>("CourseId") .HasColumnType("integer"); + b.Property<int?>("EvaluationId") + .HasColumnType("integer"); + b.Property<bool>("IsVideoConference") .HasColumnType("boolean"); @@ -40,6 +43,9 @@ namespace Tsi1.DataLayer.Migrations b.HasIndex("CourseId"); + b.HasIndex("EvaluationId") + .IsUnique(); + b.ToTable("Activities"); }); @@ -165,6 +171,66 @@ namespace Tsi1.DataLayer.Migrations b.ToTable("Courses"); }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Evaluation", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("EvaluationTypeId") + .HasColumnType("integer"); + + b.Property<bool>("IsCompleted") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationTypeId"); + + b.ToTable("Evaluations"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationInscription", b => + { + b.Property<int>("EvaluationId") + .HasColumnType("integer"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<decimal>("Grade") + .HasColumnType("decimal(5,2)"); + + b.Property<bool>("HasAttended") + .HasColumnType("boolean"); + + b.HasKey("EvaluationId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("EvaluationInscriptions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("EvaluationTypes"); + }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b => { b.Property<int>("Id") @@ -172,6 +238,9 @@ namespace Tsi1.DataLayer.Migrations .HasColumnType("integer") .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + b.Property<bool>("IsSubmission") + .HasColumnType("boolean"); + b.Property<string>("Name") .IsRequired() .HasColumnType("character varying(50)"); @@ -180,11 +249,17 @@ namespace Tsi1.DataLayer.Migrations .IsRequired() .HasColumnType("character varying(1000)"); + b.Property<int?>("SubmissionId") + .HasColumnType("integer"); + b.HasKey("Id"); b.HasIndex("Path") .IsUnique(); + b.HasIndex("SubmissionId") + .IsUnique(); + b.ToTable("Files"); }); @@ -476,6 +551,38 @@ namespace Tsi1.DataLayer.Migrations b.ToTable("StudentCourses"); }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Submission", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("EvaluationId") + .HasColumnType("integer"); + + b.Property<int>("FileId") + .HasColumnType("integer"); + + b.Property<decimal>("Grade") + .HasColumnType("decimal(5,2)"); + + b.Property<bool>("IsCompleted") + .HasColumnType("boolean"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationId"); + + b.HasIndex("StudentId", "FileId") + .IsUnique(); + + b.ToTable("Submissions"); + }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => { b.Property<int>("Id") @@ -678,6 +785,10 @@ namespace Tsi1.DataLayer.Migrations .HasForeignKey("CourseId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", "Evaluation") + .WithOne("Activity") + .HasForeignKey("Tsi1.DataLayer.Entities.Activity", "EvaluationId"); }); modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b => @@ -722,6 +833,37 @@ namespace Tsi1.DataLayer.Migrations .IsRequired(); }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Evaluation", b => + { + b.HasOne("Tsi1.DataLayer.Entities.EvaluationType", "EvaluationType") + .WithMany() + .HasForeignKey("EvaluationTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.EvaluationInscription", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", "Evaluation") + .WithMany("EvaluationInscriptions") + .HasForeignKey("EvaluationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("EvaluationInscriptions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Submission", "Submission") + .WithOne("File") + .HasForeignKey("Tsi1.DataLayer.Entities.File", "SubmissionId"); + }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b => { b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") @@ -866,6 +1008,19 @@ namespace Tsi1.DataLayer.Migrations .IsRequired(); }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Submission", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Evaluation", null) + .WithMany("Submissions") + .HasForeignKey("EvaluationId"); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => { b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") diff --git a/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs b/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs index e99928ee77fb9fa542636f2ac80da04901557926..cef2ed04e914bc9f2a34468270426eb90e72e347 100644 --- a/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs +++ b/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs @@ -35,8 +35,11 @@ namespace Tsi1.DataLayer public DbSet<Communication> Communications { get; set; } public DbSet<Activity> Activities { get; set; } public DbSet<Attendance> Attendances { get; set; } + public DbSet<Evaluation> Evaluations { get; set; } + public DbSet<EvaluationInscription> EvaluationInscriptions { get; set; } + public DbSet<Submission> Submissions { get; set; } + public DbSet<EvaluationType> EvaluationTypes { get; set; } - public DbSet<Grade> Grades { get; set; } @@ -70,7 +73,10 @@ namespace Tsi1.DataLayer modelBuilder.ApplyConfiguration(new CommunicationConfiguration()); modelBuilder.ApplyConfiguration(new ActivityConfiguration()); modelBuilder.ApplyConfiguration(new AttendanceConfiguration()); - modelBuilder.ApplyConfiguration(new GradeConfiguration()); + modelBuilder.ApplyConfiguration(new EvaluationConfiguration()); + modelBuilder.ApplyConfiguration(new EvaluationInscriptionConfiguration()); + modelBuilder.ApplyConfiguration(new SubmissionConfiguration()); + modelBuilder.ApplyConfiguration(new EvaluationTypeConfiguration()); } } }