diff --git a/CandidateReviewBusinessLogic/BusinessLogic/AssessmentLogic.cs b/CandidateReviewBusinessLogic/BusinessLogic/AssessmentLogic.cs index fe5efbb..1ba42d6 100644 --- a/CandidateReviewBusinessLogic/BusinessLogic/AssessmentLogic.cs +++ b/CandidateReviewBusinessLogic/BusinessLogic/AssessmentLogic.cs @@ -3,6 +3,7 @@ using CandidateReviewContracts.BusinessLogicsContracts; using CandidateReviewContracts.SearchModels; using CandidateReviewContracts.StoragesContracts; using CandidateReviewContracts.ViewModels; +using CandidateReviewDataModels.Models; using Microsoft.Extensions.Logging; using System.Text.RegularExpressions; @@ -17,17 +18,52 @@ namespace CandidateReviewBusinessLogic.BusinessLogic _logger = logger; _assessmentStorage = assessmentStorage; } - public bool Create(AssessmentBindingModel model) + + public bool AddCriterionToAssessment(AssessmentSearchModel model, ICriterionModel criterion, int value) { - CheckModel(model); - if (_assessmentStorage.Insert(model) == null) + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + + if (criterion == null) + { + throw new ArgumentNullException(nameof(criterion)); + } + + var element = _assessmentStorage.GetElement(model); + + if (element == null) { - _logger.LogWarning("Insert operation failed"); return false; } + + element.AssessmentCriterions[element.Id] = (criterion, value); + + _assessmentStorage.Update(new AssessmentBindingModel + { + Id = element.Id, + UserId = element.UserId, + ResumeId = element.ResumeId, + Comment = element.Comment, + AssessmentCriterions = element.AssessmentCriterions + }); + return true; } + public int? Create(AssessmentBindingModel model) + { + CheckModel(model); + var id = _assessmentStorage.Insert(model); + if (id == null) + { + _logger.LogWarning("Insert operation failed"); + return 0; + } + return id; + } + public bool Delete(AssessmentBindingModel model) { CheckModel(model, false); diff --git a/CandidateReviewBusinessLogic/BusinessLogic/CompanyLogic.cs b/CandidateReviewBusinessLogic/BusinessLogic/CompanyLogic.cs index 909a826..44f3e22 100644 --- a/CandidateReviewBusinessLogic/BusinessLogic/CompanyLogic.cs +++ b/CandidateReviewBusinessLogic/BusinessLogic/CompanyLogic.cs @@ -45,22 +45,6 @@ namespace CandidateReviewBusinessLogic.BusinessLogic return true; } - /*public CompanyViewModel? ReadElement(CompanySearchModel model) - { - if (model == null) - { - throw new ArgumentNullException(nameof(model)); - } - var element = _сompanyStorage.GetElement(model); - if (element == null) - { - _logger.LogWarning("ReadElement element not found"); - return null; - } - _logger.LogInformation("ReadElement find. Id: {Id}", element.Id); - return element; - }*/ - public CompanyViewModel? ReadElement(CompanySearchModel model) { if (model == null) diff --git a/CandidateReviewBusinessLogic/BusinessLogic/ResumeLogic.cs b/CandidateReviewBusinessLogic/BusinessLogic/ResumeLogic.cs index e4c36a2..f24aa55 100644 --- a/CandidateReviewBusinessLogic/BusinessLogic/ResumeLogic.cs +++ b/CandidateReviewBusinessLogic/BusinessLogic/ResumeLogic.cs @@ -82,7 +82,7 @@ namespace CandidateReviewBusinessLogic.BusinessLogic Description = element.Description, Skills = element.Skills, Status = element.Status, - PreviousAssessments = assessmentViewModels + Assessments = assessmentViewModels }; _logger.LogInformation("ReadElement find. Id: {Id}", element.Id); return resumeViewModel; diff --git a/CandidateReviewClientApp/Controllers/AssessmentController.cs b/CandidateReviewClientApp/Controllers/AssessmentController.cs index d7b9c31..f97989c 100644 --- a/CandidateReviewClientApp/Controllers/AssessmentController.cs +++ b/CandidateReviewClientApp/Controllers/AssessmentController.cs @@ -1,5 +1,6 @@ using CandidateReviewClientApp.Models; using CandidateReviewContracts.BindingModels; +using CandidateReviewContracts.SearchModels; using CandidateReviewContracts.ViewModels; using CandidateReviewDataModels.Models; using Microsoft.AspNetCore.Mvc; @@ -17,48 +18,53 @@ namespace CandidateReviewClientApp.Controllers } [HttpPost] - public IActionResult AddAssessment(int resumeId, string comment, Dictionary criteriaValues) + public async Task AddAssessmentCriterion(int resumeId, int[] criterion, int[] value, string comment) { string returnUrl = HttpContext.Request.Headers["Referer"].ToString(); + try { - var userId = APIClient.User?.Id; - var allCriterions = APIClient.GetRequest>("api/criterion/list"); - if (allCriterions == null || !allCriterions.Any()) + if (APIClient.User == null) { - throw new Exception("Критерии не найдены"); + throw new Exception("Необходима авторизация"); } - criteriaValues = criteriaValues.Where(kvp => kvp.Key != 0).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + if (criterion == null || value == null || criterion.Length != value.Length) + { + throw new ArgumentException("Массивы критериев и оценок должны быть не null и одинаковой длины."); + } - var assessmentCriterions = criteriaValues - .ToDictionary( - kvp => kvp.Key, - kvp => - { - var criterionViewModel = allCriterions.FirstOrDefault(c => c.Id == kvp.Key); - if (criterionViewModel == null) - { - throw new InvalidOperationException($"Критерий с ID {kvp.Key} не найден."); - } + var userId = APIClient.User?.Id; + var assessmentData = new Dictionary(); - var criterionModel = new CriterionViewModel - { - Id = criterionViewModel.Id, - Name = criterionViewModel.Name - }; - - return ((ICriterionModel)criterionModel, kvp.Value); - } - ); - - APIClient.PostRequest("api/assessment/create", new AssessmentBindingModel + var assessmentModel = new AssessmentBindingModel { ResumeId = resumeId, UserId = userId, Comment = comment, - AssessmentCriterions = assessmentCriterions - }); + AssessmentCriterions = new Dictionary() + }; + + var assessmentId = await APIClient.PostRequestAsync("api/assessment/create", assessmentModel); + + for (int i = 0; i < criterion.Length; i++) + { + if (value[i] < 1 || value[i] > 5) + { + throw new ArgumentException($"Оценка для критерия {criterion[i]} должна быть от 1 до 5."); + } + + if (assessmentData.ContainsKey(assessmentId)) + { + assessmentData[assessmentId] = (new CriterionViewModel { Id = criterion[i] }, value[i]); + } + else + { + assessmentData.Add(assessmentId, (new CriterionViewModel { Id = criterion[i] }, value[i])); + } + } + + APIClient.PostRequest("api/assessment/AddCriterionToAssessment", assessmentData); return Redirect($"~/Resume/ResumeDetails/{resumeId}"); } diff --git a/CandidateReviewClientApp/Controllers/ResumeController.cs b/CandidateReviewClientApp/Controllers/ResumeController.cs index 0380062..31d86ec 100644 --- a/CandidateReviewClientApp/Controllers/ResumeController.cs +++ b/CandidateReviewClientApp/Controllers/ResumeController.cs @@ -28,12 +28,12 @@ namespace CandidateReviewClientApp.Controllers { return View(); } - + var assessments = APIClient.GetRequest>($"api/assessment/listByResumeId?id={id}"); var criterions = APIClient.GetRequest>($"api/criterion/list"); - + resume.Assessments = assessments; ViewBag.Criterions = criterions; return View(resume); - } + } [HttpGet] public async Task EditResume(int? id, int? vacancyId) diff --git a/CandidateReviewClientApp/Views/Resume/ResumeDetails.cshtml b/CandidateReviewClientApp/Views/Resume/ResumeDetails.cshtml index 7853c52..f73f58a 100644 --- a/CandidateReviewClientApp/Views/Resume/ResumeDetails.cshtml +++ b/CandidateReviewClientApp/Views/Resume/ResumeDetails.cshtml @@ -63,35 +63,28 @@ {

Оценка резюме

-
-
- @if (ViewBag.Criterions != null) - { - - @foreach (var criterion in ViewBag.Criterions) - { - var previousAssessment = Model.PreviousAssessments?.FirstOrDefault(a => a.Id == criterion.Id); - var isSelected = previousAssessment?.Id == criterion.Id ? "selected" : string.Empty; + + -
-
- -
-
- -
-
- } - } - else + @if (ViewBag.Criterions != null) + { + foreach (var criterion in ViewBag.Criterions) { -

Нет доступных критериев.

+
+
+ +
+
+ + +
+
} -
+ } + else + { +

Нет доступных критериев.

+ }
@@ -100,8 +93,6 @@
- -
@@ -114,53 +105,5 @@ diff --git a/CandidateReviewContracts/BusinessLogicsContracts/IAssessmentLogic.cs b/CandidateReviewContracts/BusinessLogicsContracts/IAssessmentLogic.cs index 061469a..bd04b45 100644 --- a/CandidateReviewContracts/BusinessLogicsContracts/IAssessmentLogic.cs +++ b/CandidateReviewContracts/BusinessLogicsContracts/IAssessmentLogic.cs @@ -1,6 +1,7 @@ using CandidateReviewContracts.BindingModels; using CandidateReviewContracts.SearchModels; using CandidateReviewContracts.ViewModels; +using CandidateReviewDataModels.Models; namespace CandidateReviewContracts.BusinessLogicsContracts { @@ -8,7 +9,8 @@ namespace CandidateReviewContracts.BusinessLogicsContracts { List? ReadList(AssessmentSearchModel? model); AssessmentViewModel? ReadElement(AssessmentSearchModel model); - bool Create(AssessmentBindingModel model); + int? Create(AssessmentBindingModel model); + bool AddCriterionToAssessment(AssessmentSearchModel model, ICriterionModel criterion, int value); bool Update(AssessmentBindingModel model); bool Delete(AssessmentBindingModel model); } diff --git a/CandidateReviewContracts/StoragesContracts/IAssessmentStorage.cs b/CandidateReviewContracts/StoragesContracts/IAssessmentStorage.cs index ec65a23..525f924 100644 --- a/CandidateReviewContracts/StoragesContracts/IAssessmentStorage.cs +++ b/CandidateReviewContracts/StoragesContracts/IAssessmentStorage.cs @@ -9,7 +9,7 @@ namespace CandidateReviewContracts.StoragesContracts List GetFullList(); List GetFilteredList(AssessmentSearchModel model); AssessmentViewModel? GetElement(AssessmentSearchModel model); - AssessmentViewModel? Insert(AssessmentBindingModel model); + int? Insert(AssessmentBindingModel model); AssessmentViewModel? Update(AssessmentBindingModel model); AssessmentViewModel? Delete(AssessmentBindingModel model); } diff --git a/CandidateReviewContracts/ViewModels/ResumeViewModel.cs b/CandidateReviewContracts/ViewModels/ResumeViewModel.cs index 505ca85..8c33812 100644 --- a/CandidateReviewContracts/ViewModels/ResumeViewModel.cs +++ b/CandidateReviewContracts/ViewModels/ResumeViewModel.cs @@ -28,6 +28,6 @@ namespace CandidateReviewContracts.ViewModels public ResumeStatusEnum Status { get; set; } public int Id { get; set; } - public List PreviousAssessments { get; set; } = new(); + public List Assessments { get; set; } = new(); } } diff --git a/CandidateReviewDatabaseImplement/Implements/AssessmentStorage.cs b/CandidateReviewDatabaseImplement/Implements/AssessmentStorage.cs index 2171827..fc47e0e 100644 --- a/CandidateReviewDatabaseImplement/Implements/AssessmentStorage.cs +++ b/CandidateReviewDatabaseImplement/Implements/AssessmentStorage.cs @@ -99,7 +99,7 @@ namespace CandidateReviewDatabaseImplement.Implements .Select(x => x.GetViewModel).ToList(); } - public AssessmentViewModel? Insert(AssessmentBindingModel model) + public int? Insert(AssessmentBindingModel model) { using var context = new CandidateReviewDatabase(); var newAssessment = Assessment.Create(context, model); @@ -112,7 +112,7 @@ namespace CandidateReviewDatabaseImplement.Implements context.Assessments.Add(newAssessment); context.SaveChanges(); - return newAssessment.GetViewModel; + return newAssessment.Id; } public AssessmentViewModel? Update(AssessmentBindingModel model) diff --git a/CandidateReviewDatabaseImplement/Implements/UserStorage.cs b/CandidateReviewDatabaseImplement/Implements/UserStorage.cs index a2f46e9..57dda20 100644 --- a/CandidateReviewDatabaseImplement/Implements/UserStorage.cs +++ b/CandidateReviewDatabaseImplement/Implements/UserStorage.cs @@ -25,15 +25,22 @@ namespace CandidateReviewDatabaseImplement.Implements public UserViewModel? GetElement(UserSearchModel model) { - if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) - { - return null; - } using var context = new CandidateReviewDatabase(); - return context.Users + if (!string.IsNullOrEmpty(model.Email)) + { + return context.Users .Include(x => x.Company) - .FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email) || (model.Id.HasValue && x.Id == model.Id))? + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email))? .GetViewModel; + } + + else + { + return context.Users + .Include(x => x.Company) + .FirstOrDefault(x => (x.Id == model.Id))? + .GetViewModel; + } } public List GetFilteredList(UserSearchModel model) diff --git a/CandidateReviewRestApi/Controllers/AssessmentController.cs b/CandidateReviewRestApi/Controllers/AssessmentController.cs index 74f7028..a12bbb1 100644 --- a/CandidateReviewRestApi/Controllers/AssessmentController.cs +++ b/CandidateReviewRestApi/Controllers/AssessmentController.cs @@ -2,6 +2,7 @@ using CandidateReviewContracts.BusinessLogicsContracts; using CandidateReviewContracts.SearchModels; using CandidateReviewContracts.ViewModels; +using CandidateReviewDataModels.Models; using Microsoft.AspNetCore.Mvc; namespace CandidateReviewRestApi.Controllers @@ -35,12 +36,47 @@ namespace CandidateReviewRestApi.Controllers } } - [HttpPost] - public void Create(AssessmentBindingModel model) + [HttpGet] + public List? ListByUserId(int id) { try { - _logic.Create(model); + return _logic.ReadList(new AssessmentSearchModel + { + UserId = id + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения оценок"); + throw; + } + } + + [HttpGet] + public List? ListByResumeId(int id) + { + try + { + return _logic.ReadList(new AssessmentSearchModel + { + ResumeId = id + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения оценок"); + throw; + } + } + + [HttpPost] + public int? Create(AssessmentBindingModel model) + { + try + { + int? id = _logic.Create(model); + return id; } catch (Exception ex) { @@ -48,6 +84,53 @@ namespace CandidateReviewRestApi.Controllers throw; } } + [HttpPost] + public void AddCriterionToAssessment(Dictionary model) + { + if (model == null || model.Count == 0) + { + throw new ArgumentException("Модель данных не должна быть пустой.", nameof(model)); + } + + try + { + foreach (var kvp in model) + { + var id = kvp.Key; + var (criterion, value) = kvp.Value; + + if (criterion == null) + { + continue; + } + + if (!model.ContainsKey(id)) + { + model.Add(id, (criterion, value)); + } + else + { + model[id] = (criterion, value); + } + + var success = _logic.AddCriterionToAssessment( + new AssessmentSearchModel { Id = id }, + criterion, + value + ); + + if (!success) + { + throw new Exception("Ошибка добавления критерия."); + } + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка добавления критериев."); + throw; + } + } [HttpPost] public void Update(AssessmentBindingModel model)