DepartmentProject/DepartmentPortal/Department/DepartmentBusinessLogic/BusinessLogics/GenericBusinessLogic/StudentMarkSyncHistoryBusinessLogic.cs

380 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// Логика работы с историями синхронизации оценок
/// </summary>
public class StudentMarkSyncHistoryBusinessLogic : GenericBusinessLogic<StudentMarkSyncHistoryGetBindingModel, StudentMarkSyncHistorySetBindingModel, StudentMarkSyncHistoryListViewModel, StudentMarkSyncHistoryViewModel>, 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<bool> 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<StudentInfoListForMarkSyncModel>(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;
}
/// <summary>
/// Инициализаия всех логик для получения от них данных и сохранения новых
/// </summary>
private void InitLogics()
{
_recordLogic = DependencyManager.Instance.Resolve<IStudentMarkSyncHistoryRecordLogic>();
_enviromentSettingLogic = DependencyManager.Instance.Resolve<IEnviromentSettingLogic>();
_studentLogic = DependencyManager.Instance.Resolve<IStudentLogic>();
_disciplineLogic = DependencyManager.Instance.Resolve<IDisciplineLogic>();
_lecturerLogic = DependencyManager.Instance.Resolve<ILecturerLogic>();
_studentMarkPassedDisciplineLogic = DependencyManager.Instance.Resolve<IStudentMarkPassedDisciplineLogic>();
}
/// <summary>
/// Создаение логера действий при синхронизации приказов
/// </summary>
/// <returns></returns>
private bool CreateHistory()
{
_history = Create(new StudentMarkSyncHistorySetBindingModel { SyncDate = DateTime.Now });
if (_history == null)
{
Errors.Add(("Ошибка создание истории", "Не удалось создать историю"));
return false;
}
return true;
}
/// <summary>
/// Получение адреса сервера
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// Получение клиента для работы с сервисом приказов
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
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<StudentMarkPassedDisciplineViewModel, StudentMarkPassedDisciplineSetBindingModel>(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}");
}
}
}
}
/// <summary>
/// Получение семестра
/// </summary>
/// <param name="bill"></param>
/// <returns></returns>
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.Нулевой,
};
/// <summary>
/// Получение типа отчетности: зачет, экзамен..
/// </summary>
/// <param name="bill"></param>
/// <returns></returns>
private static DisciplineReportingType GetDisicplineReportingType(StudentMarkSyncModel bill) => bill.controlType switch
{
"Зачет" => DisciplineReportingType.Зачет,
"Дифференцированный зачет" => DisciplineReportingType.ЗачетСОценкой,
"Курсовая работа" => DisciplineReportingType.КурсоваяРабота,
"Курсовой проект" => DisciplineReportingType.КурсовойПроект,
"Экзамен" => DisciplineReportingType.Экзамен,
_ => DisciplineReportingType.Неопределено,
};
/// <summary>
/// Определение результата сдачи зачета/экзамена
/// </summary>
/// <param name="bill"></param>
/// <returns></returns>
private static MarkDisciplinePassedType GetMark(StudentMarkSyncModel bill) => bill.grade switch
{
"Неявка" => MarkDisciplinePassedType.НеЯвился,
"Зачтено" => MarkDisciplinePassedType.Зачет,
"Неудовлетворительно" => MarkDisciplinePassedType.НеУдовлетворительно,
"Удовлетворительно" => MarkDisciplinePassedType.Удовлетворительно,
"Хорошо" => MarkDisciplinePassedType.Хорошо,
"Отлично" => MarkDisciplinePassedType.Отлично,
_ => MarkDisciplinePassedType.НеСдано,
};
/// <summary>
/// Сохранение лога с ошибками
/// </summary>
/// <param name="errors"></param>
/// <param name="title"></param>
/// <param name="message"></param>
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)));
}
/// <summary>
/// Сохранение лога
/// </summary>
/// <param name="info"></param>
private void SaveLog(string info)
{
_recordLogic.Create(new StudentMarkSyncHistoryRecordSetBindingModel
{
StudentMarkSyncHistoryId = _history.Id,
Information = info
});
}
}
}