2022-03-19 22:48:13 +04:00
using CoreDatabase ;
2022-03-18 22:55:48 +04:00
using CoreDatabase.Models.Department ;
2022-03-19 22:48:13 +04:00
using CoreModels.Enums.Department ;
using DepartmentContract.BindingModels ;
using DepartmentContract.Services.IGenericEntityService ;
using DepartmentContract.ViewModels ;
2021-04-11 20:49:26 +04:00
using DepartmentDatabaseImplementation.Models ;
2021-04-06 22:07:11 +04:00
using Microsoft.EntityFrameworkCore ;
using System ;
2021-04-11 20:49:26 +04:00
using System.Collections.Generic ;
2021-04-06 22:07:11 +04:00
using System.Linq ;
2021-04-11 20:49:26 +04:00
using System.Xml.Linq ;
2022-03-20 10:10:44 +04:00
using ToolsModule.ManagmentEntity ;
using ToolsModule.ManagmentExtension ;
2021-04-06 22:07:11 +04:00
2022-03-19 22:48:13 +04:00
namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntityService
2021-04-06 22:07:11 +04:00
{
2022-03-18 21:34:16 +04:00
/// <summary>
/// Реализация IAcademicPlanService
/// </summary>
public class AcademicPlanService :
2021-04-06 22:07:11 +04:00
AbstractGenerticEntityService < AcademicPlanGetBindingModel , AcademicPlanSetBindingModel , AcademicPlan , AcademicPlanListViewModel , AcademicPlanViewModel > ,
IAcademicPlanService
{
protected override OperationResultModel AdditionalCheckingWhenAdding ( DbContext context , AcademicPlanSetBindingModel model ) = > OperationResultModel . Success ( null ) ;
2022-12-16 17:43:23 +04:00
protected override OperationResultModel AdditionalCheckingWhenDeleting ( DbContext context , AcademicPlan entity , AcademicPlanGetBindingModel model )
{
if ( context . Set < StudentGroup > ( ) . Any ( x = > x . AcademicPlanId = = model . Id & & x . AcademicCourse ! = AcademicCourse . Н е о п р е д е л е н ) )
{
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 ( ) ;
}
2022-12-16 17:43:23 +04:00
protected override AcademicPlan GetUniqueEntity ( AcademicPlanSetBindingModel model , IQueryable < AcademicPlan > query ) = > query . FirstOrDefault ( x = > x . EducationDirectionId = = model . EducationDirectionId & & x . YearStart = = model . YearStart & & x . Id ! = model . Id ) ;
2021-04-06 22:07:11 +04:00
protected override IQueryable < AcademicPlan > IncludingWhenReading ( IQueryable < AcademicPlan > query ) = > query . Include ( x = > x . EducationDirection ) ;
2022-12-16 17:43:23 +04:00
protected override IQueryable < AcademicPlan > OrderingWhenReading ( IQueryable < AcademicPlan > query ) = > query . OrderBy ( x = > x . EducationDirection . Cipher ) . ThenBy ( x = > x . YearStart ) ;
protected override bool AdditionalCheckForSingleGet ( AcademicPlanGetBindingModel model )
{
if ( model . EducationDirectionShortName . IsNotEmpty ( ) & & model . Year . HasValue )
{
return true ;
}
return base . AdditionalCheckForSingleGet ( model ) ;
}
protected override AcademicPlan GetSingleRecord ( IQueryable < AcademicPlan > list , AcademicPlanGetBindingModel model )
{
if ( model . EducationDirectionShortName . IsNotEmpty ( ) & & model . Year . HasValue )
{
return list . FirstOrDefault ( x = > x . EducationDirection . ShortName = = model . EducationDirectionShortName & & x . YearStart = = model . Year ) ;
}
return base . GetSingleRecord ( list , model ) ;
}
2021-04-11 20:49:26 +04:00
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 ) ;
2022-12-16 17:43:23 +04:00
if ( parentDiscipilne ! = default )
2021-04-11 20:49:26 +04:00
{
2022-12-16 17:43:23 +04:00
parent = context . AcademicPlanRecords . FirstOrDefault ( apr = >
2021-04-11 20:49:26 +04:00
apr . AcademicPlanId = = model . AcademicPlanId & &
apr . DisciplineId = = parentDiscipilne . Entity . Id & &
2022-03-18 21:34:16 +04:00
apr . Semester = = hour . Semester ) ;
2021-04-11 20:49:26 +04:00
2022-12-16 17:43:23 +04:00
if ( parent = = null )
2021-04-11 20:49:26 +04:00
{
2022-12-16 17:43:23 +04:00
// возмжно, родитель будет описан позже, заполняем данными дочернего класса пока что
parent = new AcademicPlanRecord
{
AcademicPlanId = model . AcademicPlanId ,
DisciplineId = parentDiscipilne . Entity . Id ,
InDepartment = inKafedra ,
Semester = 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 ( ) ;
}
2021-04-11 20:49:26 +04:00
2022-12-16 17:43:23 +04:00
if ( ! parent . IsParent )
{
parent . IsParent = true ;
context . SaveChanges ( ) ;
}
}
2021-04-11 20:49:26 +04:00
}
#endregion
#region З а п и с ь у ч е б н о г о п л а н а
var record = context . AcademicPlanRecords . FirstOrDefault ( apr = >
apr . AcademicPlanId = = model . AcademicPlanId & &
apr . DisciplineId = = discipline . Id & &
2022-03-18 21:34:16 +04:00
apr . Semester = = hour . Semester ) ;
2021-04-11 20:49:26 +04:00
if ( record = = null )
{
record = new AcademicPlanRecord
{
AcademicPlanId = model . AcademicPlanId ,
DisciplineId = discipline . Id ,
Zet = zet . IsNotEmpty ( ) ? Convert . ToInt32 ( zet ) : 0 ,
2022-03-18 21:34:16 +04:00
Semester = hour . Semester ,
2021-04-11 20:49:26 +04:00
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
}
}