DepartmentProject/DepartmentPortal/Department/DepartmentBusinessLogic/BusinessLogics/OrderSyncHistoryBusinessLogic.cs

558 lines
26 KiB
C#
Raw Normal View History

using DepartmentBusinessLogic.BindingModels;
using DepartmentBusinessLogic.Enums;
using DepartmentBusinessLogic.HelperModels;
using DepartmentBusinessLogic.Interfaces;
using DepartmentBusinessLogic.ViewModels;
using ModuleTools.BusinessLogics;
using ModuleTools.Enums;
using ModuleTools.Extensions;
using SecurityBusinessLogic.BindingModels;
using SecurityBusinessLogic.BusinessLogics;
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;
namespace DepartmentBusinessLogic.BusinessLogics
{
/// <summary>
/// Логика работы с историями синхронизации приказов
/// </summary>
public class OrderSyncHistoryBusinessLogic : GenericBusinessLogic<OrderSyncHistoryGetBindingModel, OrderSyncHistorySetBindingModel, OrderSyncHistoryListViewModel, OrderSyncHistoryViewModel>
{
private OrderSyncHistoryRecordBusinessLogic _recordLogic;
private EnviromentSettingBusinessLogic _enviromentSettingLogic;
private StudentGroupBusinessLogic _groupsLogic;
private StudentBusinessLogic _studentLogic;
private UserBusinessLogic _userLogic;
private OrderBusinessLogic _orderLogic;
private OrderStudentRecordBusinessLogic _orderStudentRecordLogic;
public OrderSyncHistoryBusinessLogic(IOrderSyncHistoryService service) : base(service, "Синхронизация Приказов", AccessOperation.СинхронизацияПриказов) { }
public async Task<bool> SyncOrders()
{
var history = await CreateAsync(new OrderSyncHistorySetBindingModel { SyncDate = DateTime.Now });
if (history == null)
{
Errors.Add(("Ошибка создание истории", "Не удалось создать историю"));
return false;
}
_recordLogic = DependencyManager.Instance.Resolve<OrderSyncHistoryRecordBusinessLogic>();
_enviromentSettingLogic = DependencyManager.Instance.Resolve<EnviromentSettingBusinessLogic>();
_groupsLogic = DependencyManager.Instance.Resolve<StudentGroupBusinessLogic>();
_studentLogic = DependencyManager.Instance.Resolve<StudentBusinessLogic>();
_orderLogic = DependencyManager.Instance.Resolve<OrderBusinessLogic>();
_orderStudentRecordLogic = DependencyManager.Instance.Resolve<OrderStudentRecordBusinessLogic>();
_userLogic = DependencyManager.Instance.Resolve<UserBusinessLogic>();
var address = (await _enviromentSettingLogic.GetListAsync(new EnviromentSettingGetBindingModel { Key = "SyncStudentOrderIpAddress" }))?.List?.FirstOrDefault();
if (address == null || address.Value.IsEmpty())
{
Errors = _enviromentSettingLogic.Errors;
Errors.Add(("Ошибка получения данных", "Не удалось получить адрес серверая для получения приказов по студентам"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, Errors.Select(x => x.Message))
});
return false;
}
var username = (await _enviromentSettingLogic.GetListAsync(new EnviromentSettingGetBindingModel { Key = "SyncStudentOrderUserName" }))?.List?.FirstOrDefault();
if (username == null || username.Value.IsEmpty())
{
Errors = _enviromentSettingLogic.Errors;
Errors.Add(("Ошибка получения данных", "Не удалось получить имя пользователя для получения приказов по студентам"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, Errors.Select(x => x.Message))
});
return false;
}
var password = (await _enviromentSettingLogic.GetListAsync(new EnviromentSettingGetBindingModel { Key = "SyncStudentOrderPassword" }))?.List?.FirstOrDefault();
if (password == null || password.Value.IsEmpty())
{
Errors = _enviromentSettingLogic.Errors;
Errors.Add(("Ошибка получения данных", "Не удалось получить пароль для получения приказов по студентам"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, Errors.Select(x => x.Message))
});
return false;
}
var client = new HttpClient
{
BaseAddress = new Uri(address.Value)
};
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}")));
// авторизация
// получение списка студентов
HttpResponseMessage response = await client.GetAsync($"{address.Value}/univer/hs/Ulstu_StudentsInfo/v1/GetCurrentStudentsOfDepartment");
if (!response.IsSuccessStatusCode)
{
Errors.Add(("Ошибка получения данных", "Не удалось получить список студентов с сервера"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, Errors.Select(x => x.Message))
});
return false;
}
var studentFromServer = JsonSerializer.Deserialize<StudentListSyncModel>(response.Content.ReadAsStringAsync().Result);
if (studentFromServer.CurrentStudentsList.Count == 0)
{
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = "Полученный список студентов пустой"
});
return true;
}
var groups = await _groupsLogic.GetListAsync(new StudentGroupGetBindingModel());
if (groups == null || groups.List == null)
{
Errors = _groupsLogic.Errors;
Errors.Add(("Ошибка получения данных", "Не удалось получить список групп"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, Errors.Select(x => x.Message))
});
return false;
}
var students = await _studentLogic.GetListAsync(new StudentGetBindingModel());
if (students == null || students.List == null)
{
Errors = _studentLogic.Errors;
Errors.Add(("Ошибка получения данных", "Не удалось получить список студентов"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, Errors.Select(x => x.Message))
});
return false;
}
foreach (var student in students.List)
{
var studentSync = studentFromServer.CurrentStudentsList.FirstOrDefault(x => x.recordBookName == student.NumberOfBook);
// студент не найден, значит он ушел с кафедры, выясняем почему
if (studentSync == null)
{
await SyncStudentOrders(history, student, groups.List, client, address.Value);
}
// не совпадение групп
else if (student.StudentGroupName != studentSync.groupName)
{
await SyncStudentOrders(history, student, groups.List, client, address.Value);
}
studentFromServer.CurrentStudentsList.Remove(studentSync);
}
// новые студенты и восстановленцы
foreach (var student in studentFromServer.CurrentStudentsList)
{
var deletedStudent = await _studentLogic.GetElementAsync(new StudentGetBindingModel { NumberOfBook = student.recordBookName });
if (deletedStudent == null && _studentLogic.Errors.FirstOrDefault(x => x.Message == "Элемент удален") != default)
{
// восстановленец
deletedStudent = await _studentLogic.RestoreAsync(new StudentGetBindingModel { NumberOfBook = student.recordBookName });
if (deletedStudent == null)
{
var errors = _studentLogic.Errors;
errors.Add(("Ошибка при восстановлении студента", $"Не удалось восстановить студента {student.lastName} {student.firstName} {student.patronymicName}"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, errors.Select(x => x.Message))
});
continue;
}
var deletedUser = await _userLogic.RestoreAsync(new UserGetBindingModel { Id = deletedStudent.UserId });
if (deletedUser == null)
{
var errors = _userLogic.Errors;
errors.Add(("Ошибка при восстановлении пользователя студента", $"Не удалось восстановить пользователя студента {student.lastName} {student.firstName} {student.patronymicName}"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, errors.Select(x => x.Message))
});
continue;
}
await SyncStudentOrders(history, deletedStudent, groups.List, client, address.Value);
continue;
}
var user = await _userLogic.GetElementAsync(new UserGetBindingModel
{
Login = student.recordBookName
});
if (user == null)
{
if (_userLogic.Errors.Count > 0)
{
var errors = _userLogic.Errors;
errors.Add(("Ошибка получения пользователя под студента", $"Не удалось получить пользователя под студента {student.lastName} {student.firstName} {student.patronymicName}"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, errors.Select(x => x.Message))
});
continue;
}
var userName = $"{student.lastName}{(student.firstName.IsNotEmpty() ? $" {student.firstName[0]}." : string.Empty)}{(student.patronymicName.IsNotEmpty() ? $"{student.patronymicName[0]}." : string.Empty)}";
user = await _userLogic.CreateAsync(new UserSetBindingModel
{
Login = student.recordBookName,
Password = userName
});
if (user == null)
{
var errors = _userLogic.Errors;
errors.Add(("Ошибка создания пользователя под студента", $"Не удалось создать пользователя под студента {student.lastName} {student.firstName} {student.patronymicName}"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, errors.Select(x => x.Message))
});
continue;
}
}
var newStudent = await _studentLogic.CreateAsync(new StudentSetBindingModel
{
Iduniv = student.iduniv,
NumberOfBook = student.recordBookName,
UserId = user.Id,
FirstName = student.firstName,
LastName = student.lastName,
Patronymic = student.patronymicName,
StudentState = StudentState.Неопределен,
Description = string.Empty
});
if (newStudent == null)
{
var errors = _studentLogic.Errors;
errors.Add(("Ошибка добавления студента", $"Не удалось добавить студента {student.lastName} {student.firstName} {student.patronymicName}"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, errors.Select(x => x.Message))
});
continue;
}
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = $"Добавлен студент {newStudent}"
});
await SyncStudentOrders(history, newStudent, groups.List, client, address.Value);
}
return true;
}
/// <summary>
/// Синхронизация приказов по студенту
/// </summary>
/// <param name="history"></param>
/// <param name="student"></param>
/// <param name="groups"></param>
/// <param name="client"></param>
/// <param name="address"></param>
/// <returns></returns>
private async Task SyncStudentOrders(OrderSyncHistoryViewModel history, StudentViewModel student, List<StudentGroupViewModel> groups, HttpClient client, string address)
{
HttpResponseMessage response = await client.GetAsync($"{address}/univer/hs/Ulstu_StudentsInfo/v1/GetStudentOrdersByIdAndRecordBook?iduniv={student.Iduniv}&recordBookName={student.NumberOfBook}&allOrders=sppd");
if (!response.IsSuccessStatusCode)
{
Errors.Add(("Ошибка получения данных", "Не удалось получить список приказов по студенту"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, Errors.Select(x => x.Message))
});
return;
}
var syncOrders = JsonSerializer.Deserialize<StudentOrderListSyncModel>(response.Content.ReadAsStringAsync().Result);
foreach (var syncOrder in syncOrders.StudentOrders)
{
if (syncOrder.markOfApprove.ToLower() != "true")
{
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = $"Приказ {syncOrder.clericNumber} от {syncOrder.clericDate} ({syncOrder.orderTypeName}) по студенту {student} не утврежден "
});
continue;
}
if (syncOrder.clericNumber.IsEmpty())
{
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = $"Приказ без номера от {syncOrder.clericDate} ({student})"
});
continue;
}
if (syncOrder.clericDate.IsEmpty())
{
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = $"Приказ {syncOrder.clericNumber} - неизвестная дата ({student})"
});
continue;
}
var orderType = GetOrderType(syncOrder.orderTypeName);
// пропускаем приказы, которые нас не интересуют
if (orderType == OrderType.Неопределено)
{
if (syncOrder.orderTypeName != "Корректировка" && syncOrder.orderTypeName != "Назначение стипендии" &&
syncOrder.orderTypeName != "Утверждение тем курсовых работ" && syncOrder.orderTypeName != "Утверждение тем работ"
&& syncOrder.orderTypeName != "Смена ФИО")
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = $"Приказ {syncOrder.clericNumber} неопределенного типа {syncOrder.orderTypeName}"
});
continue;
}
// пытаемся найти приказ
var order = await _orderLogic.GetElementAsync(new OrderGetBindingModel
{
OrderNumber = syncOrder.clericNumber
});
if (order == null)
{
// если не нашли - пытаемся создать
order = await _orderLogic.CreateAsync(new OrderSetBindingModel
{
OrderNumber = syncOrder.clericNumber,
OrderDate = Convert.ToDateTime(syncOrder.clericDate),
OrderType = orderType
});
if (order == null)
{
var errors = _orderLogic.Errors;
errors.Add(("Ошибка добавления приказа", $"Не удалось добавить приказ {syncOrder.clericNumber} {syncOrder.clericDate}"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, errors.Select(x => x.Message))
});
continue;
}
}
Guid? studentGroupFromId = null;
Guid? studentGroupToId = null;
string info = string.Empty;
if (syncOrder.groupNameBefore.IsNotEmpty())
{
studentGroupFromId = groups.FirstOrDefault(x => x.ToString() == syncOrder.groupNameBefore)?.Id;
}
if (syncOrder.groupNameAfter.IsNotEmpty())
{
studentGroupToId = groups.FirstOrDefault(x => x.ToString() == syncOrder.groupNameAfter)?.Id;
}
// игнорируем приказы, не связанные с нашими группами
if (!studentGroupFromId.HasValue && syncOrder.groupNameBefore.IsNotEmpty()
&& !studentGroupToId.HasValue && syncOrder.groupNameAfter.IsNotEmpty())
{
continue;
}
OrderStudentMoveType orderStudentMoveType = OrderStudentMoveType.Неопределено;
switch (syncOrder.orderTypeName)
{
case "Перевод":
if (syncOrder.orderSubTypeName == "Распределение по группам")
{
orderStudentMoveType = OrderStudentMoveType.Распределить;
info = $"Распределение студента {student} в группу {groups.FirstOrDefault(x => x.Id == studentGroupToId)}";
}
else if (studentGroupFromId.HasValue && studentGroupToId.HasValue)
{
orderStudentMoveType = OrderStudentMoveType.ПеревестиНаДругоеНаправлениеКафедры;
info = $"Перевод студента {student} из группы {groups.FirstOrDefault(x => x.Id == studentGroupFromId)} в группу {groups.FirstOrDefault(x => x.Id == studentGroupToId)}";
}
else if (!studentGroupFromId.HasValue && studentGroupToId.HasValue)
{
orderStudentMoveType = OrderStudentMoveType.ПринятьПоПереводу;
info = $"Перевод студента {student} c группы {syncOrder.groupNameBefore} другой кафедры в группу {groups.FirstOrDefault(x => x.Id == studentGroupToId)}";
}
else if (studentGroupFromId.HasValue && !studentGroupToId.HasValue)
{
orderStudentMoveType = OrderStudentMoveType.УбратьПоПереводу;
info = $"Перевод студента {student} из группы {groups.FirstOrDefault(x => x.Id == studentGroupFromId)} на другую кафедру";
}
break;
case "Зачисление в вуз вне приемной кампании":
orderStudentMoveType = OrderStudentMoveType.ЗачислитьПоПриказу;
info = $"Зачисление студента {student} по приказу";
break;
case "Зачисление в вуз":
orderStudentMoveType = OrderStudentMoveType.ЗачислитьПоПриказу;
info = $"Зачисление студента {student} по приказу";
break;
case "Перевод из другого вуза":
orderStudentMoveType = OrderStudentMoveType.ПринятьПоПереводусДругогоВуза;
info = $"Перевод студента {student} с другого вуза";
break;
case "Перевод на следующий курс":
orderStudentMoveType = OrderStudentMoveType.ПеревестиНаСтаршийКурс;
info = $"Перевод студента {student} из группы {groups.FirstOrDefault(x => x.Id == studentGroupFromId)} на следующий курс в группу {groups.FirstOrDefault(x => x.Id == studentGroupToId)}";
break;
//case "Завершение обучения": // уточнить приказ
// orderStudentMoveType = OrderStudentMoveType.ОтчислитьПоСобственному;
// info = $"Отчисление студента {student} в связи с окончанием обучения";
// break;
case "Уход в академический отпуск":
DateTime? date = null;
if (syncOrder.dateEnd.IsNotEmpty())
{
date = Convert.ToDateTime(syncOrder.dateEnd);
}
orderStudentMoveType = OrderStudentMoveType.ОтправитьВАкадем;
info = $"Уход в АО студента {student} из группы {groups.FirstOrDefault(x => x.Id == studentGroupFromId)} до {date?.ToShortDateString() ?? string.Empty}";
break;
case "Продление академического отпуска":
orderStudentMoveType = OrderStudentMoveType.ПродлитьАкадем;
info = $"Продление АО студента {student}";
break;
case "Восстановление из академического отпуска":
orderStudentMoveType = OrderStudentMoveType.ВосстановитьИзАкадема;
info = $"Выход из АО студента {student} в группу {groups.FirstOrDefault(x => x.Id == studentGroupToId)}";
break;
//case "Отчисление по невыходу из академа": // уточнить приказ
// orderStudentMoveType = OrderStudentMoveType.ОтчислитьЗаНевыходСАкадема;
// info = $"Отчисление студента {student} по невыходу из академа";
// break;
case "Отчисление":
if (syncOrder.reason == "за невыполнение учебного плана")
{
orderStudentMoveType = OrderStudentMoveType.ОтчислитьЗаНеуспевамость;
info = $"Отчисление студента {student} из группы {groups.FirstOrDefault(x => x.Id == studentGroupFromId)} за неуспеваемость";
}
if (syncOrder.reason == "по собственному желанию")
{
orderStudentMoveType = OrderStudentMoveType.ОтчислитьПоСобственному;
info = $"Отчисление студента {student} из группы {groups.FirstOrDefault(x => x.Id == studentGroupFromId)} по собственному желанию";
}
break;
case "Восстановление":
orderStudentMoveType = OrderStudentMoveType.Восстановить;
info = $"Восстановление отчисленного студента {student} в группу {groups.FirstOrDefault(x => x.Id == studentGroupToId)}";
break;
}
if (orderStudentMoveType == OrderStudentMoveType.Неопределено)
{
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = $"Неизветсный приказ {syncOrder.orderTypeName} ({syncOrder.reason}) по студенту {student}"
});
continue;
}
// ищем в приказе запись по студенту
var studentOrder = await _orderStudentRecordLogic.GetElementAsync(new OrderStudentRecordGetBindingModel
{
OrderId = order.Id,
StudentId = student.Id,
OrderStudentMoveType = orderStudentMoveType
});
// если такой приказ по студенту уже есть, просто пропускаем
if (studentOrder != null)
{
continue;
}
// создаем, если не нашли
studentOrder = await _orderStudentRecordLogic.CreateAsync(new OrderStudentRecordSetBindingModel
{
OrderId = order.Id,
StudentId = student.Id,
Info = info,
OrderStudentMoveType = orderStudentMoveType,
StudentGroupFromId = studentGroupFromId,
StudentGroupToId = studentGroupToId
});
if (studentOrder == null)
{
var errors = _orderStudentRecordLogic.Errors;
errors.Add(("Ошибка добавления записи приказа по студенту", $"Не удалось добавить запись приказа {syncOrder.orderSubTypeName} по студенту {student}"));
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = string.Join(Environment.NewLine, errors.Select(x => x.Message))
});
continue;
}
await _recordLogic.CreateAsync(new OrderSyncHistoryRecordSetBindingModel
{
OrderSyncHistoryId = history.Id,
Information = $"Добавили запись к приказу {order.OrderNumber} по студенту {student} с формулировкой {info}"
});
if (orderStudentMoveType == OrderStudentMoveType.ОтчислитьВСвязиСПереводом ||
orderStudentMoveType == OrderStudentMoveType.ОтчислитьЗаНевыходСАкадема ||
orderStudentMoveType == OrderStudentMoveType.ОтчислитьЗаНеуспевамость ||
orderStudentMoveType == OrderStudentMoveType.ОтчислитьПоЗавершению ||
orderStudentMoveType == OrderStudentMoveType.ОтчислитьПоСобственному)
{
return;
}
}
}
private static OrderType GetOrderType(string orderTitle) => orderTitle switch
{
"Зачисление в вуз вне приемной кампании" => OrderType.ЗачислениеСтудентов,
"Зачисление в вуз" => OrderType.ЗачислениеСтудентов,
"Перевод из другого вуза" => OrderType.ЗачислениеСтудентов,
"Перевод" => OrderType.Перевод,
"Перевод на следующий курс" => OrderType.ДвижениеСтудентов,
"Завершение обучения" => OrderType.Отчисление,
"Уход в академический отпуск" => OrderType.ДвижениеСтудентов,
"Продление академического отпуска" => OrderType.ДвижениеСтудентов,
"Восстановление из академического отпуска" => OrderType.ДвижениеСтудентов,
"Отчисление" => OrderType.Отчисление,
"Восстановление" => OrderType.Перевод,
_ => OrderType.Неопределено,
};
}
}