DepartmentProject/DepartmentPortal/Department/DepartmentDatabaseImplementation.csproj/Implementations/AcademicPlanService.cs

469 lines
18 KiB
C#
Raw Normal View History

2021-04-06 22:07:11 +04:00
using DatabaseCore;
using DatabaseCore.Models.Department;
using DepartmentBusinessLogic.BindingModels;
using DepartmentBusinessLogic.Enums;
2021-04-06 22:07:11 +04:00
using DepartmentBusinessLogic.Interfaces;
using DepartmentBusinessLogic.ViewModels;
using DepartmentDatabaseImplementation.Models;
2021-04-06 22:07:11 +04:00
using Microsoft.EntityFrameworkCore;
using ModuleTools.Enums;
using ModuleTools.Extensions;
2021-04-06 22:07:11 +04:00
using ModuleTools.Models;
using System;
using System.Collections.Generic;
2021-04-06 22:07:11 +04:00
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
2021-04-06 22:07:11 +04:00
namespace DepartmentDatabaseImplementation.Implementations
{
/// <summary>
/// Реализация IAcademicPlanService
/// </summary>
public class AcademicPlanService :
AbstractGenerticEntityService<AcademicPlanGetBindingModel, AcademicPlanSetBindingModel, AcademicPlan, AcademicPlanListViewModel, AcademicPlanViewModel>,
IAcademicPlanService
{
protected override OperationResultModel AdditionalCheckingWhenAdding(DbContext context, AcademicPlanSetBindingModel model) => OperationResultModel.Success(null);
2021-04-12 10:01:42 +04:00
protected override OperationResultModel AdditionalCheckingWhenDeleting(DbContext context, AcademicPlan entity, AcademicPlanGetBindingModel model)
{
if (context.Set<StudentGroup>().Any(x => x.AcademicPlanId == model.Id && !x.IsDeleted))
{
return OperationResultModel.Error("Error:", "Есть учебные группы, относящиеся к этому учебному плану", ResultServiceStatusCode.ExsistItem);
}
return OperationResultModel.Success(null);
}
2021-04-06 22:07:11 +04:00
protected override IQueryable<AcademicPlan> AdditionalCheckingWhenReadingList(IQueryable<AcademicPlan> query, AcademicPlanGetBindingModel model)
{
if (model.EducationDirectionId.HasValue)
{
query = query.Where(x => x.EducationDirectionId == model.EducationDirectionId.Value);
}
return query;
}
protected override OperationResultModel AdditionalCheckingWhenUpdateing(DbContext context, AcademicPlanSetBindingModel model) => OperationResultModel.Success(null);
protected override void AdditionalDeleting(DbContext context, AcademicPlan entity, AcademicPlanGetBindingModel model)
{
var records = context.Set<AcademicPlanRecord>().Where(x => x.AcademicPlanId == model.Id);
foreach (var record in records)
{
var hours = context.Set<AcademicPlanRecordTimeNormHour>().Where(x => x.AcademicPlanRecordId == record.Id);
foreach (var hour in hours)
{
hour.IsDeleted = true;
hour.DateDelete = DateTime.Now;
}
context.SaveChanges();
record.IsDeleted = true;
record.DateDelete = DateTime.Now;
}
context.SaveChanges();
}
protected override AcademicPlan GetUniqueEntity(AcademicPlanSetBindingModel model, DbContext context) => context.Set<AcademicPlan>().FirstOrDefault(x => x.EducationDirectionId == model.EducationDirectionId && x.YearEntrance == model.YearEntrance && x.Id != model.Id);
protected override IQueryable<AcademicPlan> IncludingWhenReading(IQueryable<AcademicPlan> query) => query.Include(x => x.EducationDirection);
protected override IQueryable<AcademicPlan> OrderingWhenReading(IQueryable<AcademicPlan> query) => query.OrderBy(x => x.EducationDirection.Cipher).ThenBy(x => x.YearEntrance);
public OperationResultModel LoadPlx(AcademicPlanLoadPlxModel model)
{
using var context = DatabaseManager.GetContext;
using var transaction = context.Database.BeginTransaction();
var result = new OperationResultModel();
try
{
#region Получаем настройки
//Получаем номер кафедры
var kafedraNumber = context.EnviromentSettings.FirstOrDefault(x => x.Key == "Кафедра");
if (kafedraNumber == null)
{
throw new Exception("Настройки среды. Не найден ключ Кафедра");
}
#endregion
var academicPlan = context.AcademicPlans.Include(x => x.EducationDirection).FirstOrDefault(x => x.Id == model.AcademicPlanId && !x.IsDeleted && x.EducationDirectionId.HasValue);
if (academicPlan == null)
{
return OperationResultModel.Error("Error:", "Учебный план не найден", ResultServiceStatusCode.NotFound);
}
#region помечаем как удаленные все записи плана, потом все найденные восстановим
var aprs = context.AcademicPlanRecords.Where(x => x.AcademicPlanId == academicPlan.Id).ToList();
foreach (var apr in aprs)
{
var apres = context.AcademicPlanRecordTimeNormHours.Where(x => x.AcademicPlanRecordId == apr.Id);
foreach (var apre in apres)
{
apre.IsDeleted = true;
apre.DateDelete = DateTime.Now;
}
apr.IsDeleted = true;
apr.DateDelete = DateTime.Now;
context.SaveChanges();
}
#endregion
var xml = XDocument.Load(model.FileName)?.Element("Документ")?.Elements()?.Elements()?.Elements();
if (xml != null)
{
var plxModel = new ParsPlxModel
{
AcademicPlanId = academicPlan.Id,
BlockTypes = new(),
DisicplineTypes = new(),
DisciplineBlocks = new(),
TimeNorms = new(),
Practics = new(),
Hours = new(),
Disciplines = new()
};
#region СправочникВидОбъекта - виды дисциплин - базовая, алтернативная и т.п.
foreach (var elem in xml.Where(x => x.Name.LocalName == "СправочникВидОбъекта"))
{
plxModel.DisicplineTypes.Add((TypeName: elem.Attribute("Наименование").Value, Code: elem.Attribute("Код").Value));
}
#endregion
#region ПланыЦиклы
foreach (var elem in xml.Where(x => x.Name.LocalName == "ПланыЦиклы"))
{
plxModel.BlockTypes.Add(new BlueAsteriskBlockType
{
Identificator = elem.Attribute("Идентификатор").Value,
Code = elem.Attribute("Код").Value,
BlockName = elem.Attribute("Цикл").Value,
IsFacultative = Convert.ToBoolean(elem.Attribute("Факультативы").Value)
});
}
#endregion
#region СправочникТипОбъекта - блоки дисциплин
foreach (var elem in xml.Where(x => x.Name.LocalName == "СправочникТипОбъекта"))
{
var disciplineBlock = context.DisciplineBlocks.FirstOrDefault(x => x.DisciplineBlockBlueAsteriskName == elem.Attribute("Название").Value);
if (disciplineBlock != null)
{
plxModel.DisciplineBlocks.Add((
Code: elem.Attribute("Код").Value,
Entity: disciplineBlock
));
}
}
#endregion
#region СправочникВидыРабот - нормы времени
foreach (var elem in xml.Where(x => x.Name.LocalName == "СправочникВидыРабот"))
{
if (!plxModel.TimeNorms.Exists(x => x.Code == elem.Attribute("Код").Value))
{
var timeNorms = context.TimeNorms.Where(x => x.KindOfLoadBlueAsteriskName == elem.Attribute("Название").Value);
foreach (var tn in timeNorms)
{
plxModel.TimeNorms.Add((
Code: elem.Attribute("Код").Value,
Entity: tn
));
}
}
}
#endregion
#region СправочникВидыПрактик - нормы времени (практики)
foreach (var elem in xml.Where(x => x.Name.LocalName == "СправочникВидыПрактик"))
{
if (!plxModel.Practics.Exists(x => x.Code == elem.Attribute("Код").Value))
{
var timeNorms = context.TimeNorms.Where(x => x.KindOfLoadBlueAsteriskPracticName == elem.Attribute("Наименование").Value);
foreach (var tn in timeNorms)
{
plxModel.Practics.Add((
Code: elem.Attribute("Код").Value,
Entity: tn
));
}
}
}
#endregion
#region ПланыНовыеЧасы - часы по дисциплинам
var attributeNames = plxModel.TimeNorms.Select(x => x.Entity.KindOfLoadBlueAsteriskAttributeName).Distinct();
foreach (var elem in xml.Where(x => x.Name.LocalName == "ПланыНовыеЧасы"))
{
var objectCode = elem.Attribute("КодОбъекта")?.Value;
if (objectCode.IsEmpty())
{
throw new Exception(string.Format("Не найден атрибут КодОбъекта"));
}
var timeNormCode = elem.Attribute("КодВидаРаботы")?.Value;
if (timeNormCode.IsEmpty())
{
throw new Exception(string.Format("Не найден атрибут КодВидаРаботы"));
}
var attributeKurs = elem.Attribute("Курс")?.Value;
if (attributeKurs.IsEmpty())
{
throw new Exception(string.Format("Не найдена атрибут Курс"));
}
var attributeSemester = elem.Attribute("Семестр")?.Value;
if (attributeSemester.IsEmpty())
{
throw new Exception(string.Format("Не найдена атрибут Семестр"));
}
var semester = attributeKurs switch
{
"1" => (attributeSemester == "1") ? Semester.Первый : Semester.Второй,
"2" => (attributeSemester == "1") ? Semester.Третий : Semester.Четвертый,
"3" => (attributeSemester == "1") ? Semester.Пятый : Semester.Шестой,
"4" => (attributeSemester == "1") ? Semester.Седьмой : Semester.Восьмой,
_ => Semester.Первый,
};
var hours = new Dictionary<string, decimal>();
foreach (var attr in attributeNames)
{
if (attr.IsNotEmpty())
{
var hour = elem.Attribute(attr)?.Value;
if (hour.IsNotEmpty() && !hours.ContainsKey(attr))
{
if (decimal.TryParse(hour, out decimal h))
{
hours.Add(attr, h);
}
else
{
if (hour.Contains('.'))
{
hour = hour.Replace('.', ',');
}
else if (hour.Contains(','))
{
hour = hour.Replace(',', '.');
}
if (decimal.TryParse(hour, out h))
{
hours.Add(attr, h);
}
}
}
}
}
plxModel.Hours.Add((
DisciplineCode: objectCode,
TimeNormCode: timeNormCode,
Semester: semester,
plxModel.TimeNorms.FirstOrDefault(x => x.Code == timeNormCode).Entity,
Hours: hours
));
}
#endregion
#region ПланыСтроки - сами записи учебного плана
foreach (var elem in xml.Where(x => x.Name.LocalName == "ПланыСтроки"))
{
#region получение дисциплины
var disciplineBlock = plxModel.DisciplineBlocks.FirstOrDefault(x => x.Code == elem.Attribute("ТипОбъекта")?.Value).Entity;
if (disciplineBlock == null)
{
return OperationResultModel.Error("ошибка", $"Не найден блок дисциплин с кодом {elem.Attribute("ТипОбъекта")?.Value}", ResultServiceStatusCode.NotFound);
}
var disciplineName = elem.Attribute("Дисциплина")?.Value;
// ищем по названию в планах дисциплину
var discipline = context.Disciplines.FirstOrDefault(x => x.DisciplineBlueAsteriskName == disciplineName);
if (discipline == null)
{
// ищем по названию дисциплину
discipline = context.Disciplines.FirstOrDefault(x => x.DisciplineName == disciplineName);
if (discipline == null)
{
discipline = new Discipline
{
DisciplineName = disciplineName,
DisciplineBlockId = disciplineBlock.Id,
DisciplineBlueAsteriskName = disciplineName
};
context.Disciplines.Add(discipline);
context.SaveChanges();
}
else
{
discipline.DisciplineBlueAsteriskName = disciplineName;
context.SaveChanges();
}
}
plxModel.Discipline = (
Code: elem.Attribute("Код")?.Value,
Practic: elem.Attribute("ВидПрактики")?.Value,
Entity: discipline
);
plxModel.Disciplines.Add(plxModel.Discipline);
#endregion
//смотрим код кафедры
bool inKafedra = elem.Attribute("КодКафедры")?.Value == kafedraNumber.Value;
bool isFacultative = elem.Attribute("ДисциплинаКод")?.Value?.StartsWith("ФТД") ?? false;
var zet = elem.Attribute("ЗЕТфакт")?.Value;
// вытаскиваем часы по дисциплине
foreach (var hour in plxModel.Hours.Where(x => x.DisciplineCode == plxModel.Discipline.Code))
{
#region Родитель
AcademicPlanRecord parent = null;
var parentValue = elem.Attribute("КодРодителя")?.Value;
if (parentValue.IsNotEmpty())
{
var parentDiscipilne = plxModel.Disciplines.FirstOrDefault(x => x.Code == parentValue);
if (parentDiscipilne == default)
{
return OperationResultModel.Error("ошибка", $"Не найдена родительская дисциплина с кодом {parentValue}", ResultServiceStatusCode.NotFound);
}
parent = context.AcademicPlanRecords.FirstOrDefault(apr =>
apr.AcademicPlanId == model.AcademicPlanId &&
apr.DisciplineId == parentDiscipilne.Entity.Id &&
apr.Semester == (int)hour.Semester);
if (parent == null)
{
// возмжно, родитель будет описан позже, заполняем данными дочернего класса пока что
parent = new AcademicPlanRecord
{
AcademicPlanId = model.AcademicPlanId,
DisciplineId = parentDiscipilne.Entity.Id,
InDepartment = inKafedra,
Semester = (int)hour.Semester,
Zet = zet.IsNotEmpty() ? Convert.ToInt32(zet) : 0,
IsParent = true,
IsFacultative = isFacultative
};
context.AcademicPlanRecords.Add(parent);
context.SaveChanges();
}
else if (parent.IsDeleted)
{
parent.IsDeleted = false;
parent.DateDelete = null;
context.SaveChanges();
}
if (!parent.IsParent)
{
parent.IsParent = true;
context.SaveChanges();
}
}
#endregion
#region Запись учебного плана
var record = context.AcademicPlanRecords.FirstOrDefault(apr =>
apr.AcademicPlanId == model.AcademicPlanId &&
apr.DisciplineId == discipline.Id &&
apr.Semester == (int)hour.Semester);
if (record == null)
{
record = new AcademicPlanRecord
{
AcademicPlanId = model.AcademicPlanId,
DisciplineId = discipline.Id,
Zet = zet.IsNotEmpty() ? Convert.ToInt32(zet) : 0,
Semester = (int)hour.Semester,
AcademicPlanRecordParentId = parent?.Id,
IsParent = false,
IsFacultative = isFacultative,
InDepartment = inKafedra
};
context.AcademicPlanRecords.Add(record);
context.SaveChanges();
}
else if (record.IsDeleted)
{
record.IsDeleted = false;
record.DateDelete = null;
context.SaveChanges();
}
#endregion
#region
if (record != null)
{
var timeNorms = new List<TimeNorm>();
// если перед нами практика, то выбираем только один нужный тип нагрузки
if (plxModel.Discipline.Practic.IsNotEmpty())
{
timeNorms.AddRange(plxModel.Practics.Where(x => x.Code == hour.TimeNormCode &&
x.Entity.DisciplineBlockId == plxModel.Discipline.Entity.DisciplineBlockId &&
(!x.Entity.TimeNormEducationDirectionQualification.HasValue ||
x.Entity.TimeNormEducationDirectionQualification == academicPlan.EducationDirection.Qualification) &&
x.Code == plxModel.Discipline.Practic).Select(x => x.Entity));
}
else
{
timeNorms.AddRange(plxModel.TimeNorms.Where(x => x.Code == hour.TimeNormCode &&
x.Entity.DisciplineBlockId == plxModel.Discipline.Entity.DisciplineBlockId &&
(!x.Entity.TimeNormEducationDirectionQualification.HasValue ||
x.Entity.TimeNormEducationDirectionQualification == academicPlan.EducationDirection.Qualification)).Select(x => x.Entity));
}
foreach (var timeNorm in timeNorms)
{
decimal planHours = 1;
if (timeNorm.KindOfLoadBlueAsteriskAttributeName.IsNotEmpty())
{
if (!hour.Hours.ContainsKey(timeNorm.KindOfLoadBlueAsteriskAttributeName))
{
return OperationResultModel.Error("ошибка",
$"Не найдена атрибут {timeNorm.KindOfLoadBlueAsteriskAttributeName} по дисциплине с кодом {plxModel.Discipline.Code}", ResultServiceStatusCode.NotFound);
}
planHours = Math.Abs(hour.Hours[timeNorm.KindOfLoadBlueAsteriskAttributeName]);
}
var recordelement = context.AcademicPlanRecordTimeNormHours.FirstOrDefault(apre =>
apre.AcademicPlanRecordId == record.Id &&
apre.TimeNormId == timeNorm.Id);
if (recordelement == null)
{
context.AcademicPlanRecordTimeNormHours.Add(new AcademicPlanRecordTimeNormHour
{
AcademicPlanRecordId = record.Id,
TimeNormId = timeNorm.Id,
PlanHours = planHours
});
}
else
{
if (recordelement.IsDeleted)
{
recordelement.IsDeleted = false;
recordelement.DateDelete = null;
}
recordelement.PlanHours = planHours;
}
context.SaveChanges();
}
}
#endregion
}
}
#endregion
}
transaction.Commit();
return result;
}
catch (Exception ex)
{
transaction.Rollback();
return OperationResultModel.Error(ex, ResultServiceStatusCode.Error);
}
}
2021-04-06 22:07:11 +04:00
}
}