using CoreModels.Enums.Department; using DepartmentBusinessLogic.HelperModels; using DepartmentContract.BindingModels; using DepartmentContract.Logics.IGenericEntityLogic; using DepartmentContract.Services.IGenericEntityService; using DepartmentContract.ViewModels; using SecurityContract.BindingModels; using SecurityContract.Logics.IGenericEntityLogic; using SecurityContract.ViewModels; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Text.Json; using System.Threading.Tasks; using ToolsModule.ManagmentDependency; using ToolsModule.ManagmentEntity; using ToolsModule.ManagmentExtension; using ToolsModule.ManagmentMapping; using ToolsModule.ManagmentSecurity; namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic { /// /// Логика работы с историями синхронизации оценок /// public class StudentMarkSyncHistoryBusinessLogic : GenericBusinessLogic, IStudentMarkSyncHistoryLogic { private IStudentMarkSyncHistoryRecordLogic _recordLogic; private IEnviromentSettingLogic _enviromentSettingLogic; private IStudentLogic _studentLogic; private IDisciplineLogic _disciplineLogic; private ILecturerLogic _lecturerLogic; private IStudentMarkPassedDisciplineLogic _studentMarkPassedDisciplineLogic; private StudentMarkSyncHistoryViewModel _history; public StudentMarkSyncHistoryBusinessLogic(IStudentMarkSyncHistoryService service) : base(service, "Синхронизация Оценок", AccessOperation.ОценкиСтудентов) { } public async Task SyncMarks() { InitLogics(); // создание логов по операции синхронизации приказов if (!CreateHistory()) { return false; } // получение адреса сервера с приказами var address = GetAddress(); if (address == null) { return false; } // подключение клиента для отправки запросов к серверу var client = GetClinet(address); if (client == null) { return false; } // получение списка оценок var response = await client.GetAsync($"{address.Value}/univer/hs/Ulstu_StudentsInfo/v1/GetCurrentStudentsOfDepartmentGrades"); if (!response.IsSuccessStatusCode) { SaveLog("Не удалось получить список оценок студента с сервера"); return false; } var studentFromServer = JsonSerializer.Deserialize(await response.Content.ReadAsStringAsync()); if (studentFromServer == null || studentFromServer.arrayOfStudentsGrades == null) { SaveLog("Не удалось распознать список приказов по студенту"); return false; } if (studentFromServer.arrayOfStudentsGrades.Length == 0) { SaveLog("Полученный список студентов пустой"); return false; } var students = _studentLogic.GetList(new StudentGetBindingModel()); if (students == null || students.List == null) { SaveErrors(_studentLogic.Errors, "Ошибка получения данных", "Не удалось получить список студентов с базы"); return false; } foreach (var student in students.List) { var marks = studentFromServer.arrayOfStudentsGrades.FirstOrDefault(x => x.recordBook == student.NumberOfBook); if (marks == null || marks.bills == null || marks.bills.Length == 0) { SaveLog($"По студенту {student} ({student.NumberOfBook}) не найдено оценок"); continue; } SyncMarks(student, marks.bills); } return true; } /// /// Инициализаия всех логик для получения от них данных и сохранения новых /// private void InitLogics() { _recordLogic = DependencyManager.Instance.Resolve(); _enviromentSettingLogic = DependencyManager.Instance.Resolve(); _studentLogic = DependencyManager.Instance.Resolve(); _disciplineLogic = DependencyManager.Instance.Resolve(); _lecturerLogic = DependencyManager.Instance.Resolve(); _studentMarkPassedDisciplineLogic = DependencyManager.Instance.Resolve(); } /// /// Создаение логера действий при синхронизации приказов /// /// private bool CreateHistory() { _history = Create(new StudentMarkSyncHistorySetBindingModel { SyncDate = DateTime.Now }); if (_history == null) { Errors.Add(("Ошибка создание истории", "Не удалось создать историю")); return false; } return true; } /// /// Получение адреса сервера /// /// private EnviromentSettingViewModel GetAddress() { var address = _enviromentSettingLogic.GetList(new EnviromentSettingGetBindingModel { Key = "SyncStudentOrderIpAddress" })?.List?.FirstOrDefault(); if (address == null || address.Value.IsEmpty()) { SaveErrors(_enviromentSettingLogic.Errors, "Ошибка получения данных", "Не удалось получить адрес сервера для получения приказов по студентам"); return null; } return address; } /// /// Получение клиента для работы с сервисом приказов /// /// /// private HttpClient GetClinet(EnviromentSettingViewModel address) { var username = _enviromentSettingLogic.GetList(new EnviromentSettingGetBindingModel { Key = "SyncStudentOrderUserName" })?.List?.FirstOrDefault(); if (username == null || username.Value.IsEmpty()) { SaveErrors(_enviromentSettingLogic.Errors, "Ошибка получения данных", "Не удалось получить имя пользователя для получения приказов по студентам"); return null; } var password = _enviromentSettingLogic.GetList(new EnviromentSettingGetBindingModel { Key = "SyncStudentOrderPassword" })?.List?.FirstOrDefault(); if (password == null || password.Value.IsEmpty()) { SaveErrors(_enviromentSettingLogic.Errors, "Ошибка получения данных", "Не удалось получить пароль для получения приказов по студентам"); return null; } var client = new HttpClient { BaseAddress = new Uri(address.Value), Timeout = TimeSpan.FromMinutes(10) }; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username.Value}:{password.Value}"))); return client; } private void SyncMarks(StudentViewModel student, StudentMarkSyncModel[] bills) { var marks = _studentMarkPassedDisciplineLogic.GetList(new StudentMarkPassedDisciplineGetBindingModel { StudentId = student.Id }); if (marks == null || marks.List == null) { SaveErrors(_studentLogic.Errors, "Ошибка получения данных", $"Не удалось получить список оценок студента {student} с базы"); return; } var studentBills = bills.ToList(); foreach (var bill in bills) { var disciplines = _disciplineLogic.GetList(new DisciplineGetBindingModel { DisciplineName = bill.disciplineName }); if (disciplines == null || disciplines.List == null || disciplines.List.Count == 0) { SaveLog($"Не найдена дисциплина {bill.disciplineName}"); continue; } var discipline = disciplines.List.First(); var sb = new StringBuilder(); LecturerViewModel lecturer = null; var teachers = bill.teacher.Split(",", StringSplitOptions.RemoveEmptyEntries); foreach (var retacher in teachers) { var lecturers = _lecturerLogic.GetList(new LecturerGetBindingModel { FIO = bill.teacher }); if (lecturers != null && lecturers.List != null && lecturers.List.Count > 0) { lecturer = lecturers.List.First(); break; } } if (lecturer == null) { sb.Append($"Преподаватель: {bill.teacher} "); } var semester = GetSemester(bill); if (semester == Semester.Нулевой) { sb.Append($"Семестр: {bill.semester} "); } var type = GetDisicplineReportingType(bill); if (type == DisciplineReportingType.Неопределено) { sb.Append($"Тип: {bill.controlType} "); } var mark = GetMark(bill); if (mark == MarkDisciplinePassedType.НеСдано) { sb.Append($"Оценка: {bill.grade} "); } var date = Convert.ToDateTime(bill.controlTypeDate); var isDirection = bill.documentType != "Аттестационная ведомость"; var markFound = marks.List.FirstOrDefault(x => x.DisciplineId == discipline.Id && x.StudentId == student.Id && x.Semester == semester && x.DisciplineReportingType == type && x.DateAffixing.Date == date.Date); if (markFound != null) { if (markFound.Mark != mark || markFound.IsDirection != isDirection || markFound.LecturerId != lecturer?.Id) { markFound.Mark = mark; markFound.IsDirection = isDirection; markFound.LecturerId = lecturer?.Id; markFound = _studentMarkPassedDisciplineLogic.Update(Mapper.MapToClass(markFound, true)); if (markFound == null) { SaveErrors(_studentMarkPassedDisciplineLogic.Errors, "Ошибка изменения данных", $"Не удалось обновить оценку студента {student}"); } else { SaveLog($"Оценка обновлена: {student}, {bill.disciplineName}, {semester}, {type}, {mark}, {lecturer?.ToString()}"); } } if (markFound != null) { marks.List.RemoveAll(x => x.Id == markFound.Id); } } else { var newMark = _studentMarkPassedDisciplineLogic.Create(new StudentMarkPassedDisciplineSetBindingModel { DisciplineId = discipline.Id, StudentId = student.Id, Semester = semester, DisciplineReportingType = type, Mark = mark, DateAffixing = date, IsDirection = isDirection, LecturerId = lecturer?.Id, AddiionalInfo = sb.ToString() }); if (newMark == null) { SaveErrors(_studentMarkPassedDisciplineLogic.Errors, "Ошибка добавления данных", $"Не удалось добавить оценку студента {student}"); } else { SaveLog($"Оценка добавлена: {student}, {bill.disciplineName}, {semester}, {type}, {mark}, {lecturer?.ToString()}"); } } } if (marks.List.Count > 0) { foreach (var mark in marks.List) { SaveLog($"Попытка удаления оценки: {student}, {mark}"); if (!_studentMarkPassedDisciplineLogic.Delete(new StudentMarkPassedDisciplineGetBindingModel { Id = mark.Id })) { SaveErrors(_studentMarkPassedDisciplineLogic.Errors, "Ошибка удаления данных", $"Не удалось удалить оценку студента {student}"); } } } } /// /// Получение семестра /// /// /// private static Semester GetSemester(StudentMarkSyncModel bill) => Convert.ToInt32(bill.semester) switch { 1 => Semester.Первый, 2 => Semester.Второй, 3 => Semester.Третий, 4 => Semester.Четвертый, 5 => Semester.Пятый, 6 => Semester.Шестой, 7 => Semester.Седьмой, 8 => Semester.Восьмой, 9 => Semester.Девятый, 10 => Semester.Десятый, _ => Semester.Нулевой, }; /// /// Получение типа отчетности: зачет, экзамен.. /// /// /// private static DisciplineReportingType GetDisicplineReportingType(StudentMarkSyncModel bill) => bill.controlType switch { "Зачет" => DisciplineReportingType.Зачет, "Дифференцированный зачет" => DisciplineReportingType.ЗачетСОценкой, "Курсовая работа" => DisciplineReportingType.КурсоваяРабота, "Курсовой проект" => DisciplineReportingType.КурсовойПроект, "Экзамен" => DisciplineReportingType.Экзамен, _ => DisciplineReportingType.Неопределено, }; /// /// Определение результата сдачи зачета/экзамена /// /// /// private static MarkDisciplinePassedType GetMark(StudentMarkSyncModel bill) => bill.grade switch { "Неявка" => MarkDisciplinePassedType.НеЯвился, "Зачтено" => MarkDisciplinePassedType.Зачет, "Неудовлетворительно" => MarkDisciplinePassedType.НеУдовлетворительно, "Удовлетворительно" => MarkDisciplinePassedType.Удовлетворительно, "Хорошо" => MarkDisciplinePassedType.Хорошо, "Отлично" => MarkDisciplinePassedType.Отлично, _ => MarkDisciplinePassedType.НеСдано, }; /// /// Сохранение лога с ошибками /// /// /// /// private void SaveErrors(List<(string Title, string Message)> errors, string title, string message) { if (_history == null) { return; } Errors = errors ?? new List<(string Title, string Message)>(); Errors.Add((title, message)); SaveLog(string.Join(Environment.NewLine, Errors.Select(x => x.Message))); } /// /// Сохранение лога /// /// private void SaveLog(string info) { _recordLogic.Create(new StudentMarkSyncHistoryRecordSetBindingModel { StudentMarkSyncHistoryId = _history.Id, Information = info }); } } }