наработки

This commit is contained in:
kotcheshir73 2022-12-16 17:43:23 +04:00
parent 7f91c8086f
commit 070f2129e4
46 changed files with 3882 additions and 1187 deletions

View File

@ -52,21 +52,19 @@ namespace CoreDatabase
modelBuilder.Entity<TimeNorm>().HasIndex(d => new { d.TimeNormName, d.TimeNormShortName }).IsUnique();
modelBuilder.Entity<AcademicPlan>().HasIndex(d => new { d.EducationDirectionId, d.CreateDate }).IsUnique();
modelBuilder.Entity<AcademicPlan>().HasIndex(d => new { d.EducationDirectionId, d.YearStart }).IsUnique();
modelBuilder.Entity<AcademicPlanRecord>().HasIndex(d => new { d.AcademicPlanId, d.DisciplineId, d.Semester }).IsUnique();
modelBuilder.Entity<AcademicPlanRecordTimeNormHour>().HasIndex(d => new { d.AcademicPlanRecordId, d.TimeNormId }).IsUnique();
modelBuilder.Entity<EnrollmentYear>().HasIndex(d => new { d.AcademicPlanId, d.YearEntrance }).IsUnique();
// ругается на циклическое каскадное удаление, так что по нормам времени убираем ее
modelBuilder.Entity<AcademicPlanRecordTimeNormHour>()
.HasOne(x => x.TimeNorm)
.WithMany(x => x.AcademicPlanRecordTimeNormHours)
.OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<StudentGroup>().HasIndex(d => new { d.EducationDirectionId, d.AcademicCourse, d.GroupNumber }).IsUnique();
modelBuilder.Entity<StudentGroup>().HasIndex(d => new { d.AcademicPlanId, d.YearEntrance, d.GroupNumber }).IsUnique();
modelBuilder.Entity<Student>().HasIndex(d => new { d.NumberOfBook }).IsUnique();
@ -124,7 +122,6 @@ namespace CoreDatabase
public virtual DbSet<OrderStudentRecord> OrderStudentRecords { set; get; }
public virtual DbSet<OrderSyncHistory> OrderSyncHistories { set; get; }
public virtual DbSet<OrderSyncHistoryRecord> OrderSyncHistoryRecords { set; get; }
public virtual DbSet<EnrollmentYear> EnrollmentYears { set; get; }
#endregion
}
}

View File

@ -0,0 +1,152 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace CoreDatabase.Migrations
{
public partial class ChangeStudentGroupLogic : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_StudentGroups_EducationDirections_EducationDirectionId",
table: "StudentGroups");
migrationBuilder.DropForeignKey(
name: "FK_Students_EnrollmentYears_EnrollmentYearId",
table: "Students");
migrationBuilder.DropTable(
name: "EnrollmentYears");
migrationBuilder.DropIndex(
name: "IX_Students_EnrollmentYearId",
table: "Students");
migrationBuilder.DropIndex(
name: "IX_StudentGroups_EducationDirectionId_AcademicCourse_GroupNumber",
table: "StudentGroups");
migrationBuilder.DropColumn(
name: "EnrollmentYearId",
table: "Students");
migrationBuilder.RenameColumn(
name: "EducationDirectionId",
table: "StudentGroups",
newName: "AcademicPlanId");
migrationBuilder.RenameColumn(
name: "AcademicCourse",
table: "StudentGroups",
newName: "YearFinish");
migrationBuilder.AddColumn<int>(
name: "YearEntrance",
table: "StudentGroups",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateIndex(
name: "IX_StudentGroups_AcademicPlanId_YearEntrance_GroupNumber",
table: "StudentGroups",
columns: new[] { "AcademicPlanId", "YearEntrance", "GroupNumber" },
unique: true);
migrationBuilder.AddForeignKey(
name: "FK_StudentGroups_AcademicPlans_AcademicPlanId",
table: "StudentGroups",
column: "AcademicPlanId",
principalTable: "AcademicPlans",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_StudentGroups_AcademicPlans_AcademicPlanId",
table: "StudentGroups");
migrationBuilder.DropIndex(
name: "IX_StudentGroups_AcademicPlanId_YearEntrance_GroupNumber",
table: "StudentGroups");
migrationBuilder.DropColumn(
name: "YearEntrance",
table: "StudentGroups");
migrationBuilder.RenameColumn(
name: "YearFinish",
table: "StudentGroups",
newName: "AcademicCourse");
migrationBuilder.RenameColumn(
name: "AcademicPlanId",
table: "StudentGroups",
newName: "EducationDirectionId");
migrationBuilder.AddColumn<Guid>(
name: "EnrollmentYearId",
table: "Students",
type: "uniqueidentifier",
nullable: true);
migrationBuilder.CreateTable(
name: "EnrollmentYears",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
AcademicPlanId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false),
DateDelete = table.Column<DateTime>(type: "datetime2", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false),
YearEntrance = table.Column<int>(type: "int", nullable: false),
YearFinish = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_EnrollmentYears", x => x.Id);
table.ForeignKey(
name: "FK_EnrollmentYears_AcademicPlans_AcademicPlanId",
column: x => x.AcademicPlanId,
principalTable: "AcademicPlans",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Students_EnrollmentYearId",
table: "Students",
column: "EnrollmentYearId");
migrationBuilder.CreateIndex(
name: "IX_StudentGroups_EducationDirectionId_AcademicCourse_GroupNumber",
table: "StudentGroups",
columns: new[] { "EducationDirectionId", "AcademicCourse", "GroupNumber" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_EnrollmentYears_AcademicPlanId_YearEntrance",
table: "EnrollmentYears",
columns: new[] { "AcademicPlanId", "YearEntrance" },
unique: true);
migrationBuilder.AddForeignKey(
name: "FK_StudentGroups_EducationDirections_EducationDirectionId",
table: "StudentGroups",
column: "EducationDirectionId",
principalTable: "EducationDirections",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Students_EnrollmentYears_EnrollmentYearId",
table: "Students",
column: "EnrollmentYearId",
principalTable: "EnrollmentYears",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
}
}

View File

@ -0,0 +1,65 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace CoreDatabase.Migrations
{
public partial class UpdateAcademicPlanSetYearStart : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AcademicPlans_EducationDirectionId_CreateDate",
table: "AcademicPlans");
migrationBuilder.AddColumn<int>(
name: "YearStart",
table: "AcademicPlans",
type: "int",
nullable: false,
defaultValue: 0);
//требуется для создания уникального индекса IX_AcademicPlans_EducationDirectionId_YearStart, если уже есть записи в AcademicPlans
migrationBuilder.Sql(
@"
UPDATE AcademicPlans
SET YearStart = YEAR(CreateDate)
");
migrationBuilder.DropColumn(
name: "CreateDate",
table: "AcademicPlans");
migrationBuilder.CreateIndex(
name: "IX_AcademicPlans_EducationDirectionId_YearStart",
table: "AcademicPlans",
columns: new[] { "EducationDirectionId", "YearStart" },
unique: true,
filter: "[EducationDirectionId] IS NOT NULL");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AcademicPlans_EducationDirectionId_YearStart",
table: "AcademicPlans");
migrationBuilder.DropColumn(
name: "YearStart",
table: "AcademicPlans");
migrationBuilder.AddColumn<DateTime>(
name: "CreateDate",
table: "AcademicPlans",
type: "datetime2",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.CreateIndex(
name: "IX_AcademicPlans_EducationDirectionId_CreateDate",
table: "AcademicPlans",
columns: new[] { "EducationDirectionId", "CreateDate" },
unique: true,
filter: "[EducationDirectionId] IS NOT NULL");
}
}
}

View File

@ -24,9 +24,6 @@ namespace CoreDatabase.Migrations
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreateDate")
.HasColumnType("datetime2");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
@ -42,9 +39,12 @@ namespace CoreDatabase.Migrations
b.Property<DateTime>("LastUpdateDate")
.HasColumnType("datetime2");
b.Property<int>("YearStart")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("EducationDirectionId", "CreateDate")
b.HasIndex("EducationDirectionId", "YearStart")
.IsUnique()
.HasFilter("[EducationDirectionId] IS NOT NULL");
@ -448,37 +448,6 @@ namespace CoreDatabase.Migrations
b.ToTable("EmployeePosts");
});
modelBuilder.Entity("CoreDatabase.Models.Department.EnrollmentYear", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("AcademicPlanId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateDelete")
.HasColumnType("datetime2");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<int>("YearEntrance")
.HasColumnType("int");
b.Property<int>("YearFinish")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("AcademicPlanId", "YearEntrance")
.IsUnique();
b.ToTable("EnrollmentYears");
});
modelBuilder.Entity("CoreDatabase.Models.Department.Lecturer", b =>
{
b.Property<Guid>("Id")
@ -822,9 +791,6 @@ namespace CoreDatabase.Migrations
b.Property<string>("Email")
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("EnrollmentYearId")
.HasColumnType("uniqueidentifier");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
@ -866,8 +832,6 @@ namespace CoreDatabase.Migrations
b.HasIndex("BasicDepartmentId");
b.HasIndex("EnrollmentYearId");
b.HasIndex("NumberOfBook")
.IsUnique();
@ -883,8 +847,8 @@ namespace CoreDatabase.Migrations
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<int>("AcademicCourse")
.HasColumnType("int");
b.Property<Guid>("AcademicPlanId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
@ -892,9 +856,6 @@ namespace CoreDatabase.Migrations
b.Property<DateTime?>("DateDelete")
.HasColumnType("datetime2");
b.Property<Guid>("EducationDirectionId")
.HasColumnType("uniqueidentifier");
b.Property<int>("GroupNumber")
.HasColumnType("int");
@ -904,11 +865,17 @@ namespace CoreDatabase.Migrations
b.Property<Guid?>("LecturerId")
.HasColumnType("uniqueidentifier");
b.Property<int>("YearEntrance")
.HasColumnType("int");
b.Property<int>("YearFinish")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("LecturerId");
b.HasIndex("EducationDirectionId", "AcademicCourse", "GroupNumber")
b.HasIndex("AcademicPlanId", "YearEntrance", "GroupNumber")
.IsUnique();
b.ToTable("StudentGroups");
@ -1267,17 +1234,6 @@ namespace CoreDatabase.Migrations
b.Navigation("Post");
});
modelBuilder.Entity("CoreDatabase.Models.Department.EnrollmentYear", b =>
{
b.HasOne("CoreDatabase.Models.Department.AcademicPlan", "AcademicPlan")
.WithMany()
.HasForeignKey("AcademicPlanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AcademicPlan");
});
modelBuilder.Entity("CoreDatabase.Models.Department.Lecturer", b =>
{
b.HasOne("CoreDatabase.Models.Department.LecturerAcademicDegree", "LecturerAcademicDegree")
@ -1370,10 +1326,6 @@ namespace CoreDatabase.Migrations
.WithMany("Students")
.HasForeignKey("BasicDepartmentId");
b.HasOne("CoreDatabase.Models.Department.EnrollmentYear", "EnrollmentYear")
.WithMany("Students")
.HasForeignKey("EnrollmentYearId");
b.HasOne("CoreDatabase.Models.Department.StudentGroup", "StudentGroup")
.WithMany("Students")
.HasForeignKey("StudentGroupId");
@ -1386,8 +1338,6 @@ namespace CoreDatabase.Migrations
b.Navigation("BasicDepartment");
b.Navigation("EnrollmentYear");
b.Navigation("StudentGroup");
b.Navigation("User");
@ -1395,9 +1345,9 @@ namespace CoreDatabase.Migrations
modelBuilder.Entity("CoreDatabase.Models.Department.StudentGroup", b =>
{
b.HasOne("CoreDatabase.Models.Department.EducationDirection", "EducationDirection")
b.HasOne("CoreDatabase.Models.Department.AcademicPlan", "AcademicPlan")
.WithMany("StudentGroups")
.HasForeignKey("EducationDirectionId")
.HasForeignKey("AcademicPlanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
@ -1405,7 +1355,7 @@ namespace CoreDatabase.Migrations
.WithMany("StudentGroups")
.HasForeignKey("LecturerId");
b.Navigation("EducationDirection");
b.Navigation("AcademicPlan");
b.Navigation("Lecturer");
});
@ -1454,6 +1404,8 @@ namespace CoreDatabase.Migrations
modelBuilder.Entity("CoreDatabase.Models.Department.AcademicPlan", b =>
{
b.Navigation("AcademicPlanRecords");
b.Navigation("StudentGroups");
});
modelBuilder.Entity("CoreDatabase.Models.Department.AcademicPlanRecord", b =>
@ -1483,8 +1435,6 @@ namespace CoreDatabase.Migrations
modelBuilder.Entity("CoreDatabase.Models.Department.EducationDirection", b =>
{
b.Navigation("AcademicPlans");
b.Navigation("StudentGroups");
});
modelBuilder.Entity("CoreDatabase.Models.Department.Employee", b =>
@ -1494,11 +1444,6 @@ namespace CoreDatabase.Migrations
b.Navigation("EmployeePosts");
});
modelBuilder.Entity("CoreDatabase.Models.Department.EnrollmentYear", b =>
{
b.Navigation("Students");
});
modelBuilder.Entity("CoreDatabase.Models.Department.Lecturer", b =>
{
b.Navigation("BasicDepartments");

View File

@ -16,7 +16,7 @@ namespace CoreDatabase.Models.Department
[DataMember]
[Required(ErrorMessage = "required")]
public DateTime CreateDate { get; set; }
public int YearStart { get; set; }
[DataMember]
[Required(ErrorMessage = "required")]
@ -31,10 +31,13 @@ namespace CoreDatabase.Models.Department
[ForeignKey("AcademicPlanId")]
public virtual List<AcademicPlanRecord> AcademicPlanRecords { get; set; }
[ForeignKey("AcademicPlanId")]
public virtual List<StudentGroup> StudentGroups { get; set; }
//-------------------------------------------------------------------------
public AcademicPlan SecurityCheck(AcademicPlan entity, bool allowFullData) => entity;
public override string ToString() => $"{EducationDirection?.ShortName}({EducationDirection?.Profile}): {CreateDate:d}";
public override string ToString() => $"{EducationDirection?.ShortName}({EducationDirection?.Profile}): {YearStart}";
}
}

View File

@ -48,9 +48,6 @@ namespace CoreDatabase.Models.Department
[ForeignKey("EducationDirectionId")]
public virtual List<AcademicPlan> AcademicPlans { get; set; }
[ForeignKey("EducationDirectionId")]
public virtual List<StudentGroup> StudentGroups { get; set; }
//-------------------------------------------------------------------------
public EducationDirection SecurityCheck(EducationDirection entity, bool allowFullData) => entity;

View File

@ -1,40 +0,0 @@
using CoreModels.ModelsDepartment;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
using ToolsModule.ManagmentSecurity;
namespace CoreDatabase.Models.Department
{
[DataContract]
public class EnrollmentYear : BaseEntity, IEntitySecurityExtenstion<EnrollmentYear>, IEnrollmentYearModel
{
[DataMember]
public Guid AcademicPlanId { get; set; }
[DataMember]
[Required(ErrorMessage = "required")]
public int YearEntrance { get; set; }
[DataMember]
[Required(ErrorMessage = "required")]
public int YearFinish { get; set; }
//-------------------------------------------------------------------------
public virtual AcademicPlan AcademicPlan { get; set; }
//-------------------------------------------------------------------------
[ForeignKey("EnrollmentYearId")]
public virtual List<Student> Students { get; set; }
//-------------------------------------------------------------------------
public EnrollmentYear SecurityCheck(EnrollmentYear entity, bool allowFullData) => entity;
public override string ToString() => $"{AcademicPlan?.EducationDirection?.ShortName}({AcademicPlan?.EducationDirection?.Profile}): {YearEntrance}-{YearFinish}";
}
}

View File

@ -21,9 +21,6 @@ namespace CoreDatabase.Models.Department
[DataMember]
public Guid? StudentGroupId { get; set; }
[DataMember]
public Guid? EnrollmentYearId { get; set; }
[DataMember]
public Guid? BasicDepartmentId { get; set; }
@ -67,8 +64,6 @@ namespace CoreDatabase.Models.Department
public virtual StudentGroup StudentGroup { get; set; }
public virtual EnrollmentYear EnrollmentYear { get; set; }
public virtual BasicDepartment BasicDepartment { get; set; }
//-------------------------------------------------------------------------

View File

@ -15,22 +15,39 @@ namespace CoreDatabase.Models.Department
{
[DataMember]
[Required(ErrorMessage = "required")]
public Guid EducationDirectionId { get; set; }
public Guid AcademicPlanId { get; set; }
[DataMember]
[Required(ErrorMessage = "required")]
public int YearEntrance { get; set; }
[DataMember]
[Required(ErrorMessage = "required")]
public int YearFinish { get; set; }
[NotMapped]
public AcademicCourse AcademicCourse => DateTime.Now.Year + DateTime.Now.Month / 8 > YearFinish
? AcademicCourse.Неопределен
: (DateTime.Now.Year + DateTime.Now.Month / 8 - YearEntrance) switch
{
1 => AcademicCourse.Курс_1,
2 => AcademicCourse.Курс_2,
3 => AcademicCourse.Курс_3,
4 => AcademicCourse.Курс_4,
5 => AcademicCourse.Курс_5,
_ => AcademicCourse.Неопределен,
};
[DataMember]
[Required(ErrorMessage = "required")]
public int GroupNumber { get; set; }
[DataMember]
[Required(ErrorMessage = "required")]
public AcademicCourse AcademicCourse { get; set; }
[DataMember]
public Guid? LecturerId { get; set; }
//-------------------------------------------------------------------------
public virtual EducationDirection EducationDirection { get; set; }
public virtual AcademicPlan AcademicPlan { get; set; }
public virtual Lecturer Lecturer { get; set; }
@ -49,7 +66,7 @@ namespace CoreDatabase.Models.Department
public StudentGroup SecurityCheck(StudentGroup entity, bool allowFullData) => entity;
public override string ToString() => $"{EducationDirection?.ShortName}-{AcademicCourse}{GroupNumber}";
public override string ToString() => $"{AcademicPlan?.EducationDirection?.ShortName}-{((int)AcademicCourse)}{GroupNumber}";
public int GetStudnetsByState(StudentState state)
{

View File

@ -26,6 +26,6 @@ namespace CoreDatabase.Models.Security
public UserRole SecurityCheck(UserRole entity, bool allowFullData) => entity;
public override string ToString() => $"{Role.RoleName}-{User.UserName}";
public override string ToString() => $"{Role?.RoleName}-{User?.UserName}";
}
}

View File

@ -5,12 +5,16 @@
/// </summary>
public enum AcademicCourse
{
Неопределен = 0,
Курс_1 = 1,
Курс_2 = 2,
Курс_3 = 3,
Курс_4 = 4
Курс_4 = 4,
Курс_5 = 5
}
}

View File

@ -42,11 +42,6 @@
/// </summary>
ПеревестиНаДругоеНаправлениеКафедры = 7,
/// <summary>
/// Студент переводится с нашей кафедры на другую
/// </summary>
УбратьПоПереводу = 8,
/// <summary>
/// Уход в акакдем студента
/// </summary>
@ -68,7 +63,7 @@
ОтчислитьЗаНевыходСАкадема = 13,
/// <summary>
/// Уход студента в другой ВУЗ
/// Уход студента в другой ВУЗ/ другую кафедру
/// </summary>
ОтчислитьВСвязиСПереводом = 20,
@ -85,6 +80,11 @@
/// <summary>
/// Восстановление студента после отчисления по собственному
/// </summary>
Восстановить = 23
Восстановить = 23,
/// <summary>
/// Отчисление студента из-за неоплаты обучения
/// </summary>
ОтчислитьЗаНеоплату = 24
}
}

View File

@ -10,7 +10,7 @@ namespace CoreModels.ModelsDepartment
{
Guid? EducationDirectionId { get; }
DateTime CreateDate { get; }
int YearStart { get; }
DateTime LastUpdateDate { get; }
}

View File

@ -1,17 +0,0 @@
using CoreModels.Tools;
using System;
using ToolsModule.ManagmentEntity;
namespace CoreModels.ModelsDepartment
{
[EntityDescription("EnrollmentYear", "Год зачисления")]
[EntityDependency("AcademicPlan", "AcademicPlanId", "Учебный план, по которому учатся зачисленные")]
public interface IEnrollmentYearModel : IId
{
Guid AcademicPlanId { get; }
int YearEntrance { get; }
int YearFinish { get; }
}
}

View File

@ -6,11 +6,15 @@ using ToolsModule.ManagmentEntity;
namespace CoreModels.ModelsDepartment
{
[EntityDescription("StudentGroup", "Учебная группа кафедры")]
[EntityDependency("EducationDirection", "EducationDirectionId", "Направление, по которому учится группа")]
[EntityDependency("AcademicPlan", "AcademicPlanId", "Учебный план, по которому учится группа")]
[EntityDependency("Lecturer", "LecturerId", "Куратор группы")]
public interface IStudentGroupModel : IId
{
Guid EducationDirectionId { get; }
Guid AcademicPlanId { get; }
int YearEntrance { get; }
int YearFinish { get; }
int GroupNumber { get; }

View File

@ -8,7 +8,6 @@ namespace CoreModels.ModelsDepartment
[EntityDescription("Student", "Студент кафедры")]
[EntityDependency("User", "UserId", "К какому пользователю относится студент")]
[EntityDependency("StudentGroup", "StudentGroupId", "К какой группе относится студент")]
[EntityDependency("EnrollmentYear", "EnrollmentYearId", "К какому году поступления/выпуска относится")]
[EntityDependency("BasicDepartment", "BasicDepartmentId", "Базовая кафедра, к которой относится студент")]
public interface IStudentModel : IId
{
@ -16,8 +15,6 @@ namespace CoreModels.ModelsDepartment
Guid? StudentGroupId { get; }
Guid? EnrollmentYearId { get; }
Guid? BasicDepartmentId { get; }
string Iduniv { get; }

View File

@ -1,17 +0,0 @@
using DepartmentContract.BindingModels;
using DepartmentContract.Logics.IGenericEntityLogic;
using DepartmentContract.Services.IGenericEntityService;
using DepartmentContract.ViewModels;
using ToolsModule.ManagmentEntity;
using ToolsModule.ManagmentSecurity;
namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
{
/// <summary>
/// Логика работы с годом поступления
/// </summary>
public class EnrollmentYearBusinessLogic : GenericBusinessLogic<EnrollmentYearGetBindingModel, EnrollmentYearSetBindingModel, EnrollmentYearListViewModel, EnrollmentYearViewModel>, IEnrollmentYearLogic
{
public EnrollmentYearBusinessLogic(IEnrollmentYearService service) : base(service, "Года поступления", AccessOperation.УчебныеПланы) { }
}
}

View File

@ -26,7 +26,11 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
{
var studentLogic = DependencyManager.Instance.Resolve<IStudentLogic>();
var userLogic = DependencyManager.Instance.Resolve<IUserLogic>();
var student = model.StudentModel;
var student = studentLogic.GetElement(new StudentGetBindingModel
{
NumberOfBook = model.StudentModel.NumberOfBook,
IgnoreDeleted = true
});
if (student == null)
{
Errors.AddRange(studentLogic.Errors);
@ -53,16 +57,35 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
result.OrderStudentMoveType == OrderStudentMoveType.Распределить ||
result.OrderStudentMoveType == OrderStudentMoveType.ПринятьПоПереводу ||
result.OrderStudentMoveType == OrderStudentMoveType.ПринятьПоПереводусДругогоВуза ||
result.OrderStudentMoveType == OrderStudentMoveType.ПеревестиНаДругоеНаправлениеКафедры)
result.OrderStudentMoveType == OrderStudentMoveType.ПеревестиНаДругоеНаправлениеКафедры ||
result.OrderStudentMoveType == OrderStudentMoveType.ПеревестиНаСтаршийКурс)
&& student.StudentState != StudentState.Учится)
{
if (st.StudentState == StudentState.Отчислен || st.StudentState == StudentState.Ушел)
{
var deletedStudent = studentLogic.Restore(new StudentGetBindingModel { NumberOfBook = student.NumberOfBook });
if (deletedStudent == null)
{
Errors.AddRange(studentLogic.Errors);
Errors.Add(("Ошибка при восстановлении студента", $"Не удалось восстановить студента {studentName}, приказ: {result.OrderStudentMoveType}"));
return null;
}
var deletedUser = userLogic.Restore(new UserGetBindingModel { Id = deletedStudent.UserId });
if (deletedUser == null)
{
Errors.AddRange(userLogic.Errors);
Errors.Add(("Ошибка при восстановлении пользователя студента", $"Не удалось восстановить пользователя студента {studentName}"));
return null;
}
st = Mapper.MapToClass<StudentViewModel, StudentSetBindingModel>(deletedStudent, true);
}
st.StudentState = StudentState.Учится;
student = studentLogic.Update(st);
haveChages = false;
if (student == null)
{
Errors.AddRange(studentLogic.Errors);
Errors.Add(("Ошибка изменения по студенту", $"Не удалось изменить статус у студента {studentName}"));
Errors.Add(("Ошибка изменения по студенту", $"Не удалось перевести в статус 'Учится' студента {studentName}, приказ: {result.OrderStudentMoveType}"));
return null;
}
}
@ -77,7 +100,7 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
if (student == null)
{
Errors.AddRange(studentLogic.Errors);
Errors.Add(("Ошибка изменения по студенту", $"Не удалось изменить статус у студента {studentName}"));
Errors.Add(("Ошибка изменения по студенту", $"Не удалось перевести в статус 'Академ' студента {studentName}, приказ: {result.OrderStudentMoveType}"));
return null;
}
}
@ -90,7 +113,7 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
if (student == null)
{
Errors.AddRange(studentLogic.Errors);
Errors.Add(("Ошибка изменения по студенту", $"Не удалось изменить статус у студента {studentName}"));
Errors.Add(("Ошибка изменения по студенту", $"Не удалось восстановить в статус 'Учится' студента {studentName}, приказ: {result.OrderStudentMoveType}"));
return null;
}
}
@ -102,13 +125,15 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
result.OrderStudentMoveType == OrderStudentMoveType.ОтчислитьПоЗавершению) &&
student.StudentState != StudentState.Отчислен)
{
st.StudentState = result.OrderStudentMoveType == OrderStudentMoveType.ОтчислитьПоЗавершению ? StudentState.Завершил : StudentState.Отчислен;
st.StudentState = result.OrderStudentMoveType == OrderStudentMoveType.ОтчислитьПоЗавершению ? StudentState.Завершил :
result.OrderStudentMoveType == OrderStudentMoveType.ОтчислитьВСвязиСПереводом ? StudentState.Ушел :
StudentState.Отчислен;
student = studentLogic.Update(st);
haveChages = false;
if (student == null)
{
Errors.AddRange(studentLogic.Errors);
Errors.Add(("Ошибка изменения по студенту", $"Не удалось изменить статус у студента {studentName}"));
Errors.Add(("Ошибка изменения по студенту", $"Не удалось перевести в статус 'Отчислен' студента {studentName}, приказ: {result.OrderStudentMoveType}"));
return null;
}
var delete = studentLogic.Delete(new StudentGetBindingModel { Id = student.Id });
@ -133,7 +158,7 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
if (deletedStudent == null)
{
Errors.AddRange(studentLogic.Errors);
Errors.Add(("Ошибка при восстановлении студента", $"Не удалось восстановить студента {studentName}"));
Errors.Add(("Ошибка при восстановлении студента", $"Не удалось восстановить студента {studentName}, приказ: {result.OrderStudentMoveType}"));
return null;
}
var deletedUser = userLogic.Restore(new UserGetBindingModel { Id = deletedStudent.UserId });
@ -154,33 +179,6 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
}
}
if (result.OrderStudentMoveType == OrderStudentMoveType.УбратьПоПереводу && student.StudentState != StudentState.Ушел)
{
st.StudentState = StudentState.Ушел;
student = studentLogic.Update(st);
haveChages = false;
if (student == null)
{
Errors.AddRange(studentLogic.Errors);
Errors.Add(("Ошибка изменения по студенту", $"Не удалось изменить статус у студента {studentName}"));
return null;
}
var delete = studentLogic.Delete(new StudentGetBindingModel { Id = student.Id });
if (!delete)
{
Errors.AddRange(studentLogic.Errors);
Errors.Add(("Ошибка удаления студента", $"Не удалось удалить студента {studentName}"));
return null;
}
delete = userLogic.Delete(new UserGetBindingModel { Id = student.UserId });
if (!delete)
{
Errors.AddRange(studentLogic.Errors);
Errors.Add(("Ошибка удаления пользователя по студенту", $"Не удалось удалить пользователя по студенту {studentName}"));
return null;
}
}
if (haveChages)
{
student = studentLogic.Update(st);

View File

@ -18,7 +18,6 @@ using System.Threading.Tasks;
using ToolsModule.ManagmentDependency;
using ToolsModule.ManagmentEntity;
using ToolsModule.ManagmentExtension;
using ToolsModule.ManagmentMapping;
using ToolsModule.ManagmentSecurity;
namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
@ -32,6 +31,8 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
private IEnviromentSettingLogic _enviromentSettingLogic;
private IAcademicPlanLogic _academicPlanLogic;
private IStudentGroupLogic _groupsLogic;
private IStudentLogic _studentLogic;
@ -48,23 +49,32 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
private OrderSyncHistoryViewModel _history;
private StudentGroupListViewModel _groups;
public OrderSyncHistoryBusinessLogic(IOrderSyncHistoryService service) : base(service, "Синхронизация Приказов", AccessOperation.СинхронизацияПриказов) { }
/// <summary>
/// Синхронизация приказов по всем студентам
/// </summary>
/// <returns></returns>
public async Task<bool> SyncOrders()
{
InitLogics();
// создание логов по операции синхронизации приказов
if (!CreateHistory())
{
return false;
}
// получение адреса сервера с приказами
var address = GetAddress();
if (address == null)
{
return false;
}
// подключение клиента для отправки запросов к серверу
var client = GetClinet(address);
if (client == null)
{
@ -90,12 +100,7 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
return false;
}
var groups = _groupsLogic.GetList(new StudentGroupGetBindingModel());
if (groups == null || groups.List == null)
{
SaveErrors(_groupsLogic.Errors, "Ошибка получения данных", "Не удалось получить список групп с базы");
return false;
}
_groups = GetStudentGroups();
var students = _studentLogic.GetList(new StudentGetBindingModel());
if (students == null || students.List == null)
@ -107,38 +112,49 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
foreach (var student in students.List)
{
var studentSync = studentFromServer.CurrentStudentsList.FirstOrDefault(x => x.recordBookName == student.NumberOfBook);
// студент не найден, значит он ушел с кафедры, выясняем почему
if (studentSync == null)
// студент не найден, значит он ушел с кафедры, выясняем почему ИЛИ не совпадение групп
if (studentSync == null || student.StudentGroupName != studentSync.groupName)
{
await SyncStudentOrders(student, groups.List, client, address.Value);
}
// не совпадение групп
else if (student.StudentGroupName != studentSync.groupName)
{
await SyncStudentOrders(student, groups.List, client, address.Value);
await SyncStudentOrders(student, client, address.Value);
}
studentFromServer.CurrentStudentsList.Remove(studentSync);
}
// новые студенты и восстановленцы
foreach (var student in studentFromServer.CurrentStudentsList)
{
// восстановленцы
var deletedStudent = _studentLogic.GetElement(new StudentGetBindingModel { NumberOfBook = student.recordBookName, IgnoreDeleted = true });
if (deletedStudent != null)
{
await SyncStudentOrders(deletedStudent, groups.List, client, address.Value);
await SyncStudentOrders(deletedStudent, client, address.Value);
continue;
}
// новые студенты
var newStudent = CreateNewStudent(student);
if (newStudent != null)
{
SaveLog($"Добавлен студент {newStudent}");
await SyncStudentOrders(newStudent, groups.List, client, address.Value);
await SyncStudentOrders(newStudent, client, address.Value);
}
}
foreach(var group in _groups.List)
{
var grStudents = _studentLogic.GetList(new StudentGetBindingModel { StudentGroupId = group.Id });
if (grStudents?.List?.Count == 0)
{
_groupsLogic.Delete(new StudentGroupGetBindingModel { Id = group.Id });
}
}
return true;
}
/// <summary>
/// Синхронизация приказов по студенту
/// </summary>
/// <param name="studentId"></param>
/// <returns></returns>
public async Task<bool> SyncStudentOrders(Guid studentId)
{
InitLogics();
@ -161,12 +177,7 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
return false;
}
var groups = _groupsLogic.GetList(new StudentGroupGetBindingModel());
if (groups == null || groups.List == null)
{
SaveErrors(_groupsLogic.Errors, "Ошибка получения данных", "Не удалось получить список групп с базы");
return false;
}
_groups = GetStudentGroups();
var student = _studentLogic.GetElement(new StudentGetBindingModel { Id = studentId });
if (student == null)
@ -174,14 +185,18 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
SaveErrors(_studentLogic.Errors, "Ошибка получения данных", "Не удалось получить студента с базы");
return false;
}
await SyncStudentOrders(student, groups.List, client, address.Value);
await SyncStudentOrders(student, client, address.Value);
return true;
}
/// <summary>
/// Инициализаия всех логик для получения от них данных и сохранения новых
/// </summary>
private void InitLogics()
{
_recordLogic = DependencyManager.Instance.Resolve<IOrderSyncHistoryRecordLogic>();
_enviromentSettingLogic = DependencyManager.Instance.Resolve<IEnviromentSettingLogic>();
_academicPlanLogic = DependencyManager.Instance.Resolve<IAcademicPlanLogic>();
_groupsLogic = DependencyManager.Instance.Resolve<IStudentGroupLogic>();
_studentLogic = DependencyManager.Instance.Resolve<IStudentLogic>();
_orderLogic = DependencyManager.Instance.Resolve<IOrderLogic>();
@ -191,6 +206,10 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
_roleLogic = DependencyManager.Instance.Resolve<IRoleLogic>();
}
/// <summary>
/// Создаение логера действий при синхронизации приказов
/// </summary>
/// <returns></returns>
private bool CreateHistory()
{
_history = Create(new OrderSyncHistorySetBindingModel { SyncDate = DateTime.Now });
@ -202,6 +221,10 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
return true;
}
/// <summary>
/// Получение адреса сервера
/// </summary>
/// <returns></returns>
private EnviromentSettingViewModel GetAddress()
{
var address = _enviromentSettingLogic.GetList(new EnviromentSettingGetBindingModel { Key = "SyncStudentOrderIpAddress" })?.List?.FirstOrDefault();
@ -213,9 +236,13 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
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())
{
@ -241,6 +268,26 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
return client;
}
/// <summary>
/// Получение списка групп
/// </summary>
/// <returns></returns>
private StudentGroupListViewModel GetStudentGroups()
{
var sgs = _groupsLogic.GetList(new StudentGroupGetBindingModel());
if (sgs == null || sgs.List == null)
{
SaveErrors(_groupsLogic.Errors, "Ошибка получения данных", "Не удалось получить список групп с базы");
return null;
}
return sgs;
}
/// <summary>
/// Получение пользователя-студента
/// </summary>
/// <param name="student"></param>
/// <returns></returns>
private UserViewModel WorkWithUser(StudentSyncModel student)
{
var userName = $"{student.lastName}{(student.firstName.IsNotEmpty() ? $" {student.firstName[0]}." : string.Empty)}{(student.patronymicName.IsNotEmpty() ? $"{student.patronymicName[0]}." : string.Empty)}";
@ -280,6 +327,11 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
return user;
}
/// <summary>
/// Создание нового студента
/// </summary>
/// <param name="student"></param>
/// <returns></returns>
private StudentViewModel CreateNewStudent(StudentSyncModel student)
{
var user = WorkWithUser(student);
@ -315,7 +367,7 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
/// <param name="client"></param>
/// <param name="address"></param>
/// <returns></returns>
private async Task SyncStudentOrders(StudentViewModel student, List<StudentGroupViewModel> groups, HttpClient client, string address)
private async Task SyncStudentOrders(StudentViewModel student, HttpClient client, string address)
{
var response = await client.GetAsync($"{address}/univer/hs/Ulstu_StudentsInfo/v1/GetStudentOrdersByIdAndRecordBook?iduniv={student.Iduniv}&recordBookName={student.NumberOfBook}&allOrders=sppd");
if (!response.IsSuccessStatusCode)
@ -329,6 +381,10 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
SaveLog("Не удалось распознать список приказов по студенту");
return;
}
if (student.LastName == "Костенко" || student.LastName == "Киселева")
{
int c = 10;
}
foreach (var syncOrder in syncOrders.StudentOrders)
{
if (syncOrder.orderTypeName == "Утверждение тем курсовых работ" ||
@ -363,7 +419,7 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
{
if (syncOrder.orderTypeName != "Корректировка" && syncOrder.orderTypeName != "Смена ФИО")
{
SaveLog($"Приказ {syncOrder.clericNumber} неопределенного типа {syncOrder.orderTypeName}");
SaveLog($"Приказ {syncOrder.clericNumber} необрабатываемого типа {syncOrder.orderTypeName} по студенту {student}");
}
continue;
}
@ -391,20 +447,11 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
}
}
StudentGroupViewModel studentGroupFrom = null;
StudentGroupViewModel studentGroupTo = null;
if (syncOrder.groupNameBefore.IsNotEmpty())
{
syncOrder.groupNameBefore = syncOrder.groupNameBefore.Replace("пбд", "бд");
studentGroupFrom = groups.FirstOrDefault(x => x.GroupName == syncOrder.groupNameBefore || x.ToString() == syncOrder.groupNameBefore);
}
if (syncOrder.groupNameAfter.IsNotEmpty())
{
syncOrder.groupNameAfter = syncOrder.groupNameAfter.Replace("пбд", "бд");
studentGroupTo = groups.FirstOrDefault(x => x.GroupName == syncOrder.groupNameAfter || x.ToString() == syncOrder.groupNameAfter);
}
var studentGroupFrom = GetStudentGroup(syncOrder.groupNameBefore, order, false);
var studentGroupTo = GetStudentGroup(syncOrder.groupNameAfter, order, syncOrder.orderSubTypeName == "Распределение по группам");
// игнорируем приказы, не связанные с нашими группами
if (studentGroupFrom == null && syncOrder.groupNameBefore.IsNotEmpty() && studentGroupTo == null && syncOrder.groupNameAfter.IsNotEmpty())
if (studentGroupFrom == null && studentGroupTo == null && order.OrderType != OrderType.ЗачислениеСтудентов &&
syncOrder.reason != "на другой факультет")
{
continue;
}
@ -430,8 +477,6 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
continue;
}
SetYearFinish(student, studentGroupTo, order, orderStudentMoveType);
// создаем, если не нашли
var studentOrder = _orderStudentRecordLogic.Create(new OrderStudentRecordSetBindingModel
{
@ -450,18 +495,14 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
}
SaveLog($"Добавили запись к приказу {order.OrderNumber} по студенту {student} с формулировкой {info}");
if (orderStudentMoveType == OrderStudentMoveType.ОтчислитьВСвязиСПереводом ||
orderStudentMoveType == OrderStudentMoveType.ОтчислитьЗаНевыходСАкадема ||
orderStudentMoveType == OrderStudentMoveType.ОтчислитьЗаНеуспевамость ||
orderStudentMoveType == OrderStudentMoveType.ОтчислитьПоЗавершению ||
orderStudentMoveType == OrderStudentMoveType.ОтчислитьПоСобственному)
{
return;
}
}
}
/// <summary>
/// Определение типа приказа
/// </summary>
/// <param name="orderTitle"></param>
/// <returns></returns>
private static OrderType GetOrderType(string orderTitle) => orderTitle switch
{
"Зачисление в вуз вне приемной кампании" => OrderType.ЗачислениеСтудентов,
@ -480,6 +521,86 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
_ => OrderType.Неопределено,
};
/// <summary>
/// Поиск группы по названию из приказа
/// </summary>
/// <param name="studetnGroupName"></param>
/// <param name="order"></param>
/// <param name="groups"></param>
/// <returns></returns>
private StudentGroupViewModel GetStudentGroup(string studetnGroupName, OrderViewModel order, bool isGrouping)
{
if (string.IsNullOrEmpty(studetnGroupName))
{
return null;
}
studetnGroupName = studetnGroupName.Replace("пбд", "бд");// когда-то были группы-прикладники
int orderStudyYear = order.OrderDate.Year + (order.OrderDate.Month / 7) - 1; // учебный год
var group = _groups.List.FirstOrDefault(x => GetGroupName(x, orderStudyYear) == studetnGroupName);
if (group == null && isGrouping)
{
var academicPlan = _academicPlanLogic.GetElement(new AcademicPlanGetBindingModel
{
EducationDirectionShortName = studetnGroupName.Split('-')[0],
Year = orderStudyYear
});
if (academicPlan == null)
{
SaveLog($"Не найден учебный план для группы {studetnGroupName} за {orderStudyYear} год");
return null;
}
int yearFinish = academicPlan.EducationDirectionQualification == EducationDirectionQualification.Бакалавриат ? orderStudyYear + 4 :
academicPlan.EducationDirectionQualification == EducationDirectionQualification.Магистратура ? orderStudyYear + 2 : 0;
var newGroup = _groupsLogic.Create(new StudentGroupSetBindingModel
{
AcademicPlanId = academicPlan.Id,
GroupNumber = Convert.ToInt32(studetnGroupName[^1].ToString()),
LecturerId = null,
YearEntrance = orderStudyYear,
YearFinish = yearFinish
});
if (newGroup == null)
{
SaveErrors(_groupsLogic.Errors, "Ошибка созданий группы", "Не удалось создать группу");
return null;
}
_groups = GetStudentGroups();
group = _groups.List.FirstOrDefault(x => GetGroupName(x, orderStudyYear) == studetnGroupName);
}
return group;
}
/// <summary>
/// Получение именни группы в зависимости от нужного года
/// </summary>
/// <param name="group"></param>
/// <param name="orderStudyYear"></param>
/// <returns></returns>
private static string GetGroupName(StudentGroupViewModel group, int orderStudyYear)
{
var course = orderStudyYear > group.YearFinish
? AcademicCourse.Неопределен
: (orderStudyYear - group.YearEntrance) switch
{
0 => AcademicCourse.Курс_1,
1 => AcademicCourse.Курс_2,
2 => AcademicCourse.Курс_3,
3 => AcademicCourse.Курс_4,
4 => AcademicCourse.Курс_5,
_ => AcademicCourse.Неопределен,
};
return $"{group.EducationDirectionShortName}-{((int)course)}{group.GroupNumber}";
}
/// <summary>
/// Определение подтипа приказа
/// </summary>
/// <param name="student"></param>
/// <param name="syncOrder"></param>
/// <param name="studentGroupFrom"></param>
/// <param name="studentGroupTo"></param>
/// <param name="info"></param>
/// <returns></returns>
private static OrderStudentMoveType GetOrderStudentMoveType(StudentViewModel student, StudentOrderSyncModel syncOrder, StudentGroupViewModel studentGroupFrom,
StudentGroupViewModel studentGroupTo, out string info)
{
@ -502,11 +623,6 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
return OrderStudentMoveType.ПринятьПоПереводу;
}
if (studentGroupFrom != null && studentGroupTo == null)
{
info = $"Перевод студента {student} из группы {studentGroupFrom} на другую кафедру в группу {syncOrder.groupNameAfter}";
return OrderStudentMoveType.УбратьПоПереводу;
}
if (syncOrder.reason == "на другой факультет")
{
info = $"Отчисление студента {student} из группы {studentGroupFrom} в связи с переводом";
return OrderStudentMoveType.ОтчислитьВСвязиСПереводом;
@ -540,27 +656,36 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
info = $"Выход из АО студента {student} в группу {studentGroupTo}";
return OrderStudentMoveType.ВосстановитьИзАкадема;
case "Отчисление":
switch (syncOrder.reason)
if (syncOrder.reason.Contains("за невыполнение учебного плана") ||
syncOrder.reason.Contains("академическую неуспеваемость") ||
syncOrder.reason.Contains("в связи с невыполнением обучающимся обязанностей по добросовестному освоению") ||
syncOrder.reason.Contains("за невыполнение обязанностей по добросовестному освоению"))
{
case "за невыполнение учебного плана":
info = $"Отчисление студента {student} из группы {studentGroupFrom} за неуспеваемость";
return OrderStudentMoveType.ОтчислитьЗаНеуспевамость;
case "по собственному желанию":
}
if (syncOrder.reason.Contains("по собственному желанию"))
{
info = $"Отчисление студента {student} из группы {studentGroupFrom} по собственному желанию";
return OrderStudentMoveType.ОтчислитьПоСобственному;
case "в связи с невыходом из академического отпуска":
}
if (syncOrder.reason.Contains("в связи с невыходом из академического отпуска"))
{
info = $"Отчисление студента {student} из группы {studentGroupFrom} в связи с невыходм из академического отпуска";
return OrderStudentMoveType.ОтчислитьЗаНевыходСАкадема;
case "за невыполнение обязанностей по добросовестному освоению образовательной программы и выполнению учебного плана":
info = $"Отчисление студента {student} из группы {studentGroupFrom} за неуспеваемость";
return OrderStudentMoveType.ОтчислитьЗаНеуспевамость;
case "в связи с переводом в ___":
}
if (syncOrder.reason.Contains("в связи с переводом в"))
{
info = $"Отчисление студента {student} из группы {studentGroupFrom} в связи с переводом";
return OrderStudentMoveType.ОтчислитьВСвязиСПереводом;
default:
}
if (syncOrder.reason.Contains("за невыполнение условий договора"))
{
info = $"Отчисление студента {student} из группы {studentGroupFrom} в связи с не оплатой обучения";
return OrderStudentMoveType.ОтчислитьЗаНеоплату;
}
info = string.Empty;
return OrderStudentMoveType.Неопределено;
}
case "Восстановление":
info = $"Восстановление отчисленного студента {student} в группу {studentGroupTo}";
return OrderStudentMoveType.Восстановить;
@ -573,112 +698,12 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
}
}
private void SetYearFinish(StudentViewModel student, StudentGroupViewModel group, OrderViewModel order, OrderStudentMoveType studentOrderType)
{
if (student == null)
{
return;
}
int year = DateTime.Now.Year;
switch (studentOrderType)
{
// у студента не меняется год зачисления
case OrderStudentMoveType.ПродлитьАкадем:
case OrderStudentMoveType.ОтчислитьПоЗавершению:
return;
// студент уходит с текущего года обучения, сбрасываем его
case OrderStudentMoveType.Неопределено:
case OrderStudentMoveType.ОтправитьВАкадем:
case OrderStudentMoveType.ОтчислитьВСвязиСПереводом:
case OrderStudentMoveType.ОтчислитьЗаНевыходСАкадема:
case OrderStudentMoveType.ОтчислитьЗаНеуспевамость:
case OrderStudentMoveType.ОтчислитьПоСобственному:
case OrderStudentMoveType.УбратьПоПереводу:
student.EnrollmentYearId = null;
return;
// проблема с разными направлениями групп на разных курсах
case OrderStudentMoveType.ПеревестиНаСтаршийКурс:
if (student.EnrollmentYearId.HasValue)
{
return;
}
if (group == null || order == null)
{
return;
}
year = order.OrderDate.Year;
switch (group.AcademicCourse)
{
case AcademicCourse.Курс_1:
break;
case AcademicCourse.Курс_2:
year--;
break;
case AcademicCourse.Курс_3:
year -= 2;
break;
case AcademicCourse.Курс_4:
year -= 3;
break;
}
break;
// может быть зачисление проводилось без указания группы, тогда группа определится при распределении
case OrderStudentMoveType.Распределить:
if (student.EnrollmentYearId.HasValue)
{
return;
}
if (group == null || order == null)
{
return;
}
year = order.OrderDate.Year;
break;
case OrderStudentMoveType.ЗачислитьПоПриказу:
if (group == null || order == null)
{
return;
}
year = order.OrderDate.Year;
break;
case OrderStudentMoveType.ПринятьПоПереводу:
case OrderStudentMoveType.ПринятьПоПереводусДругогоВуза:
case OrderStudentMoveType.Восстановить:
case OrderStudentMoveType.ВосстановитьИзАкадема:
case OrderStudentMoveType.ПеревестиНаДругоеНаправлениеКафедры:
if (group == null || order == null)
{
return;
}
year = order.OrderDate.Month < 8 ? order.OrderDate.Year - 1 : order.OrderDate.Year;
switch (group.AcademicCourse)
{
case AcademicCourse.Курс_1:
break;
case AcademicCourse.Курс_2:
year--;
break;
case AcademicCourse.Курс_3:
year -= 2;
break;
case AcademicCourse.Курс_4:
year -= 3;
break;
}
break;
}
var logic = DependencyManager.Instance.Resolve<IEnrollmentYearLogic>();
var yearEnrollment = logic.GetElement(new EnrollmentYearGetBindingModel { EducationDirectionId = group.EducationDirectionId, Year = year });
if (yearEnrollment == null)
{
SaveErrors(logic.Errors, "Ошибка установки года выпуска студента", $"Не удалось найти год выпуска студента {student.LastName} {student.FirstName} {student.Patronymic}");
return;
}
student.EnrollmentYearId = yearEnrollment.Id;
}
/// <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)
@ -691,6 +716,10 @@ namespace DepartmentBusinessLogic.BusinessLogics.GenericBusinessLogic
SaveLog(string.Join(Environment.NewLine, Errors.Select(x => x.Message)));
}
/// <summary>
/// Сохранение лога
/// </summary>
/// <param name="info"></param>
private void SaveLog(string info)
{
_recordLogic.Create(new OrderSyncHistoryRecordSetBindingModel

View File

@ -30,7 +30,6 @@ namespace DepartmentBusinessLogic
DependencyManager.Instance.RegisterType<IAcademicPlanLogic, AcademicPlanBusinessLogic>();
DependencyManager.Instance.RegisterType<IAcademicPlanRecordLogic, AcademicPlanRecordBusinessLogic>();
DependencyManager.Instance.RegisterType<IAcademicPlanRecordTimeNormHourLogic, AcademicPlanRecordTimeNormHourBusinessLogic>();
DependencyManager.Instance.RegisterType<IEnrollmentYearLogic, EnrollmentYearBusinessLogic>();
DependencyManager.Instance.RegisterType<IStudentGroupLogic, StudentGroupBusinessLogic>();

View File

@ -11,6 +11,10 @@ namespace DepartmentContract.BindingModels
public class AcademicPlanGetBindingModel : GetBindingModel
{
public Guid? EducationDirectionId { get; set; }
public string EducationDirectionShortName { get; set; }
public int? Year { get; set; }
}
/// <summary>
@ -21,10 +25,11 @@ namespace DepartmentContract.BindingModels
public Guid? EducationDirectionId { get; set; }
[Required(ErrorMessage = "required")]
public DateTime CreateDate { get; set; }
public int YearStart { get; set; }
[Required(ErrorMessage = "required")]
public DateTime LastUpdateDate { get; set; }
}
/// <summary>

View File

@ -1,33 +0,0 @@
using CoreModels.ModelsDepartment;
using System;
using System.ComponentModel.DataAnnotations;
using ToolsModule.ManagmentEntity;
namespace DepartmentContract.BindingModels
{
/// <summary>
/// Получение года поступления
/// </summary>
public class EnrollmentYearGetBindingModel : GetBindingModel
{
public Guid? AcademicPlanId { get; set; }
public Guid? EducationDirectionId { get; set; }
public int? Year { get; set; }
}
/// <summary>
/// Сохранение года поступления
/// </summary>
public class EnrollmentYearSetBindingModel : SetBindingModel, IEnrollmentYearModel
{
public Guid AcademicPlanId { get; set; }
[Required(ErrorMessage = "required")]
public int YearEntrance { get; set; }
[Required(ErrorMessage = "required")]
public int YearFinish { get; set; }
}
}

View File

@ -15,8 +15,6 @@ namespace DepartmentContract.BindingModels
public Guid? StudentGroupId { get; set; }
public Guid? EnrollmentYearId { get; set; }
public Guid? BasicDepartmentId { get; set; }
public StudentState? StudentState { get; set; }
@ -34,8 +32,6 @@ namespace DepartmentContract.BindingModels
public Guid? StudentGroupId { get; set; }
public Guid? EnrollmentYearId { get; set; }
public Guid? BasicDepartmentId { get; set; }
[Required(ErrorMessage = "required")]

View File

@ -13,6 +13,8 @@ namespace DepartmentContract.BindingModels
{
public Guid? EducationDirectionId { get; set; }
public Guid? AcademicPlanId { get; set; }
public Guid? LecturerId { get; set; }
}
@ -22,7 +24,13 @@ namespace DepartmentContract.BindingModels
public class StudentGroupSetBindingModel : SetBindingModel, IStudentGroupModel
{
[Required(ErrorMessage = "required")]
public Guid EducationDirectionId { get; set; }
public Guid AcademicPlanId { get; set; }
[Required(ErrorMessage = "required")]
public int YearEntrance { get; set; }
[Required(ErrorMessage = "required")]
public int YearFinish { get; set; }
[Required(ErrorMessage = "required")]
public int GroupNumber { get; set; }

View File

@ -1,11 +0,0 @@
using DepartmentContract.BindingModels;
using DepartmentContract.ViewModels;
using ToolsModule.ManagmentEntity;
namespace DepartmentContract.Logics.IGenericEntityLogic
{
/// <summary>
/// Логика работы с годом поступления
/// </summary>
public interface IEnrollmentYearLogic : IGenericEntityLogic<EnrollmentYearGetBindingModel, EnrollmentYearSetBindingModel, EnrollmentYearListViewModel, EnrollmentYearViewModel> { }
}

View File

@ -1,10 +0,0 @@
using DepartmentContract.BindingModels;
using ToolsModule.ManagmentEntity;
namespace DepartmentContract.Services.IGenericEntityService
{
/// <summary>
/// Хранение годов поступления
/// </summary>
public interface IEnrollmentYearService : IGenericEntityService<EnrollmentYearGetBindingModel, EnrollmentYearSetBindingModel> { }
}

View File

@ -1,4 +1,5 @@
using CoreModels.ModelsDepartment;
using CoreModels.Enums.Department;
using CoreModels.ModelsDepartment;
using System;
using ToolsModule.ManagmentEntity;
using ToolsModule.ManagmentMapping;
@ -16,8 +17,8 @@ namespace DepartmentContract.ViewModels
[ViewModelControlElementClass(HaveDependenceEntities = true, Width = 1200, Height = 800)]
[ViewModelControlElementDependenceEntity(Title = "Записи плана", Order = 1, ParentPropertyName = "AcademicPlanId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlAcademicPlanRecordList, DepartmentWindowsDesktop")]
[ViewModelControlElementDependenceEntity(Title = ода поступления", Order = 1, ParentPropertyName = "AcademicPlanId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlEnrollmentYearList, DepartmentWindowsDesktop")]
[ViewModelControlElementDependenceEntity(Title = руппы", Order = 2, ParentPropertyName = "AcademicPlanId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlStudentGroupList, DepartmentWindowsDesktop")]
public class AcademicPlanViewModel : ElementViewModel, IAcademicPlanModel
{
[ViewModelControlElementProperty("Направление", ControlType.ControlGuid, MustHaveValue = false, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlEducationDirectionList, DepartmentWindowsDesktop")]
@ -30,13 +31,16 @@ namespace DepartmentContract.ViewModels
[ViewModelControlListProperty("Профиль")]
[MapConfiguration("EducationDirection.Profile")]
public string EducationDirectionProfile { get; set; }
[MapConfiguration("EducationDirection.Qualification")]
public EducationDirectionQualification EducationDirectionQualification { get; set; }
[ViewModelControlListProperty("Дата создания", ColumnWidth = 120, DefaultCellStyleFormat = "dd.MM.yyyy")]
[ViewModelControlElementProperty("Дата создания", ControlType.ControlDateTime, MustHaveValue = true)]
public DateTime CreateDate { get; set; }
[ViewModelControlListProperty("Год начала", ColumnWidth = 120)]
[ViewModelControlElementProperty("Год начала", ControlType.ControlInt, MustHaveValue = true)]
public int YearStart { get; set; }
[ViewModelControlListProperty("Дата последнего изменения", ColumnWidth = 120, DefaultCellStyleFormat = "dd.MM.yyyy")]
[ViewModelControlElementProperty("Дата последнего изменения", ControlType.ControlDateTime, MustHaveValue = true)]
public DateTime LastUpdateDate { get; set; }
}
}

View File

@ -17,8 +17,6 @@ namespace DepartmentContract.ViewModels
[ViewModelControlElementClass(HaveDependenceEntities = true, Width = 800, Height = 500)]
[ViewModelControlElementDependenceEntity(Title = "Учебные планы", Order = 1, ParentPropertyName = "EducationDirectionId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlAcademicPlanList, DepartmentWindowsDesktop")]
[ViewModelControlElementDependenceEntity(Title = "Группы", Order = 2, ParentPropertyName = "EducationDirectionId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlStudentGroupList, DepartmentWindowsDesktop")]
public class EducationDirectionViewModel : ElementViewModel, IEducationDirectionModel
{
[ViewModelControlListProperty("Шифр", ColumnWidth = 80)]

View File

@ -1,40 +0,0 @@
using CoreModels.ModelsDepartment;
using System;
using ToolsModule.ManagmentEntity;
using ToolsModule.ManagmentMapping;
namespace DepartmentContract.ViewModels
{
/// <summary>
/// Список учбеных планов
/// </summary>
public class EnrollmentYearListViewModel : ListViewModel<EnrollmentYearViewModel> { }
/// <summary>
/// Элемент учебного плана
/// </summary>
[ViewModelControlElementClass(HaveDependenceEntities = true, Width = 1200, Height = 800)]
[ViewModelControlElementDependenceEntity(Title = "Студенты", Order = 1, ParentPropertyName = "EnrollmentYearId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlStudentList, DepartmentWindowsDesktop")]
public class EnrollmentYearViewModel : ElementViewModel, IEnrollmentYearModel
{
[ViewModelControlElementProperty("Учебный план", ControlType.ControlGuid, MustHaveValue = false, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlAcademicPlanList, DepartmentWindowsDesktop")]
public Guid AcademicPlanId { get; set; }
[ViewModelControlListProperty("Направление")]
[MapConfiguration("AcademicPlan.EducationDirection.Cipher")]
public string EducationDirectionCipher { get; set; }
[ViewModelControlListProperty("Профиль")]
[MapConfiguration("AcademicPlan.EducationDirection.Profile")]
public string EducationDirectionProfile { get; set; }
[ViewModelControlListProperty("Дата начала", ColumnWidth = 120)]
[ViewModelControlElementProperty("Дата начала", ControlType.ControlInt, MustHaveValue = true)]
public int YearEntrance { get; set; }
[ViewModelControlListProperty("Дата окончания", ColumnWidth = 120)]
[ViewModelControlElementProperty("Дата окончания", ControlType.ControlInt, MustHaveValue = true)]
public int YearFinish { get; set; }
}
}

View File

@ -19,24 +19,30 @@ namespace DepartmentContract.ViewModels
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlStudentList, DepartmentWindowsDesktop")]
public class StudentGroupViewModel : ElementViewModel, IStudentGroupModel
{
[ViewModelControlElementProperty("Направление", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlEducationDirectionList, DepartmentWindowsDesktop")]
public Guid EducationDirectionId { get; set; }
[ViewModelControlElementProperty("Направление", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlAcademicPlanList, DepartmentWindowsDesktop")]
public Guid AcademicPlanId { get; set; }
[ViewModelControlListProperty("Шифр", ColumnWidth = 80)]
[MapConfiguration("EducationDirection.Cipher")]
[MapConfiguration("AcademicPlan.EducationDirection.Cipher")]
public string EducationDirectionCipher { get; set; }
[ViewModelControlListProperty("Профиль")]
[MapConfiguration("EducationDirection.Profile")]
[MapConfiguration("AcademicPlan.EducationDirection.Profile")]
public string EducationDirectionProfile { get; set; }
[MapConfiguration("EducationDirection.ShortName")]
[MapConfiguration("AcademicPlan.EducationDirection.ShortName")]
public string EducationDirectionShortName { get; set; }
[ViewModelControlElementProperty("Год начала", ControlType.ControlInt, MustHaveValue = true)]
public int YearEntrance { get; set; }
[ViewModelControlElementProperty("Год окончания", ControlType.ControlInt, MustHaveValue = true)]
public int YearFinish { get; set; }
[ViewModelControlListProperty("Группа")]
public string GroupName => $"{EducationDirectionShortName}-{(int)AcademicCourse}{GroupNumber}";
[ViewModelControlElementProperty("Курс", ControlType.ControlEnum, MustHaveValue = true)]
[ViewModelControlElementProperty("Курс", ControlType.ControlEnum, ReadOnly = true)]
public AcademicCourse AcademicCourse { get; set; }
[ViewModelControlListProperty("Курс")]

View File

@ -28,9 +28,6 @@ namespace DepartmentContract.ViewModels
[MapConfiguration("StudentGroup.ToString")]
public string StudentGroupName { get; set; }
[ViewModelControlElementProperty("Год выпуска", ControlType.ControlGuid, MustHaveValue = false, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlEnrollmentYearList, DepartmentWindowsDesktop")]
public Guid? EnrollmentYearId { get; set; }
[ViewModelControlElementProperty("Базовая кафедра", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlBasicDepartmentList, DepartmentWindowsDesktop")]
public Guid? BasicDepartmentId { get; set; }
@ -58,8 +55,9 @@ namespace DepartmentContract.ViewModels
public string Email { get; set; }
[ViewModelControlListProperty("Базовая кафедра")]
public bool IsBasicDepartmentId => BasicDepartmentId.HasValue ? true : false;
public bool IsBasicDepartmentId => BasicDepartmentId.HasValue;
[ViewModelControlListProperty("Описание")]
[ViewModelControlElementProperty("Описание", ControlType.ControlText)]
public string Description { get; set; }

View File

@ -31,7 +31,6 @@ namespace DepartmentDatabaseImplementation
DependencyManager.Instance.RegisterType<IAcademicPlanService, AcademicPlanService>();
DependencyManager.Instance.RegisterType<IAcademicPlanRecordService, AcademicPlanRecordService>();
DependencyManager.Instance.RegisterType<IAcademicPlanRecordTimeNormHourService, AcademicPlanRecordTimeNormHourService>();
DependencyManager.Instance.RegisterType<IEnrollmentYearService, EnrollmentYearService>();
DependencyManager.Instance.RegisterType<IStudentGroupService, StudentGroupService>();

View File

@ -24,7 +24,14 @@ namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntit
{
protected override OperationResultModel AdditionalCheckingWhenAdding(DbContext context, AcademicPlanSetBindingModel model) => OperationResultModel.Success(null);
protected override OperationResultModel AdditionalCheckingWhenDeleting(DbContext context, AcademicPlan entity, AcademicPlanGetBindingModel model) => OperationResultModel.Success(null);
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);
}
protected override IQueryable<AcademicPlan> AdditionalCheckingWhenReadingList(IQueryable<AcademicPlan> query, AcademicPlanGetBindingModel model)
{
@ -56,11 +63,29 @@ namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntit
context.SaveChanges();
}
protected override AcademicPlan GetUniqueEntity(AcademicPlanSetBindingModel model, IQueryable<AcademicPlan> query) => query.FirstOrDefault(x => x.EducationDirectionId == model.EducationDirectionId && x.CreateDate == model.CreateDate && x.Id != model.Id);
protected override AcademicPlan GetUniqueEntity(AcademicPlanSetBindingModel model, IQueryable<AcademicPlan> query) => query.FirstOrDefault(x => x.EducationDirectionId == model.EducationDirectionId && x.YearStart == model.YearStart && 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.CreateDate);
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);
}
public OperationResultModel LoadPlx(AcademicPlanLoadPlxModel model)
{
@ -311,11 +336,8 @@ namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntit
if (parentValue.IsNotEmpty())
{
var parentDiscipilne = plxModel.Disciplines.FirstOrDefault(x => x.Code == parentValue);
if (parentDiscipilne == default)
if (parentDiscipilne != default)
{
return OperationResultModel.Error("ошибка", $"Не найдена родительская дисциплина с кодом {parentValue}", ResultServiceStatusCode.NotFound);
}
parent = context.AcademicPlanRecords.FirstOrDefault(apr =>
apr.AcademicPlanId == model.AcademicPlanId &&
apr.DisciplineId == parentDiscipilne.Entity.Id &&
@ -350,6 +372,7 @@ namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntit
context.SaveChanges();
}
}
}
#endregion
#region Запись учебного плана

View File

@ -24,10 +24,6 @@ namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntit
{
return OperationResultModel.Error("Error:", "Есть учебные планы, относящиеся к этому направлению", ResultServiceStatusCode.ExsistItem);
}
if (context.Set<StudentGroup>().Any(x => x.EducationDirectionId == model.Id && !x.IsDeleted))
{
return OperationResultModel.Error("Error:", "Есть учебные группы, относящиеся к этому направлению", ResultServiceStatusCode.ExsistItem);
}
return OperationResultModel.Success(null);
}

View File

@ -1,76 +0,0 @@
using CoreDatabase;
using CoreDatabase.Models.Department;
using DepartmentContract.BindingModels;
using DepartmentContract.Services.IGenericEntityService;
using DepartmentContract.ViewModels;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using ToolsModule.ManagmentEntity;
namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntityService
{
/// <summary>
/// Реализация IEnrollmentYearService
/// </summary>
public class EnrollmentYearService :
AbstractGenerticEntityService<EnrollmentYearGetBindingModel, EnrollmentYearSetBindingModel, EnrollmentYear, EnrollmentYearListViewModel, EnrollmentYearViewModel>,
IEnrollmentYearService
{
protected override OperationResultModel AdditionalCheckingWhenAdding(DbContext context, EnrollmentYearSetBindingModel model) => OperationResultModel.Success(null);
protected override OperationResultModel AdditionalCheckingWhenDeleting(DbContext context, EnrollmentYear entity, EnrollmentYearGetBindingModel model) => OperationResultModel.Success(null);
protected override IQueryable<EnrollmentYear> AdditionalCheckingWhenReadingList(IQueryable<EnrollmentYear> query, EnrollmentYearGetBindingModel model)
{
if (model.AcademicPlanId.HasValue)
{
query = query.Where(x => x.AcademicPlanId == model.AcademicPlanId.Value);
}
if (model.EducationDirectionId.HasValue)
{
query = query.Where(x => x.AcademicPlan.EducationDirectionId == model.EducationDirectionId.Value);
}
if (model.Year.HasValue)
{
query = query.Where(x => x.YearEntrance == model.Year.Value);
}
return query;
}
protected override OperationResultModel AdditionalCheckingWhenUpdateing(DbContext context, EnrollmentYearSetBindingModel model) => OperationResultModel.Success(null);
protected override void AdditionalDeleting(DbContext context, EnrollmentYear entity, EnrollmentYearGetBindingModel model)
{
var records = context.Set<Student>().Where(x => x.EnrollmentYearId == model.Id);
foreach (var record in records)
{
record.EnrollmentYearId = null;
}
context.SaveChanges();
}
protected override EnrollmentYear GetUniqueEntity(EnrollmentYearSetBindingModel model, IQueryable<EnrollmentYear> query) => query.FirstOrDefault(x => x.AcademicPlanId == model.AcademicPlanId && x.YearEntrance == model.YearEntrance && x.Id != model.Id);
protected override IQueryable<EnrollmentYear> IncludingWhenReading(IQueryable<EnrollmentYear> query) => query.Include(x => x.AcademicPlan).Include(x => x.AcademicPlan.EducationDirection);
protected override IQueryable<EnrollmentYear> OrderingWhenReading(IQueryable<EnrollmentYear> query) => query.OrderBy(x => x.AcademicPlan.EducationDirection.Cipher).ThenBy(x => x.YearEntrance);
protected override bool AdditionalCheckForSingleGet(EnrollmentYearGetBindingModel model)
{
if (model.EducationDirectionId.HasValue && model.Year.HasValue)
{
return true;
}
return base.AdditionalCheckForSingleGet(model);
}
protected override EnrollmentYear GetSingleRecord(IQueryable<EnrollmentYear> list, EnrollmentYearGetBindingModel model)
{
if (model.EducationDirectionId.HasValue && model.Year.HasValue)
{
return list.FirstOrDefault(x => x.AcademicPlan.EducationDirectionId == model.EducationDirectionId && x.YearEntrance == model.Year);
}
return base.GetSingleRecord(list, model);
}
}
}

View File

@ -32,7 +32,11 @@ namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntit
{
if (model.EducationDirectionId.HasValue)
{
query = query.Where(x => x.EducationDirectionId == model.EducationDirectionId.Value);
query = query.Where(x => x.AcademicPlan.EducationDirectionId == model.EducationDirectionId.Value);
}
if (model.AcademicPlanId.HasValue)
{
query = query.Where(x => x.AcademicPlanId == model.AcademicPlanId.Value);
}
if (model.LecturerId.HasValue)
{
@ -54,10 +58,10 @@ namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntit
context.SaveChanges();
}
protected override StudentGroup GetUniqueEntity(StudentGroupSetBindingModel model, IQueryable<StudentGroup> query) => query.FirstOrDefault(x => x.EducationDirectionId == model.EducationDirectionId && x.AcademicCourse == model.AcademicCourse && x.GroupNumber == model.GroupNumber && x.Id != model.Id);
protected override StudentGroup GetUniqueEntity(StudentGroupSetBindingModel model, IQueryable<StudentGroup> query) => query.FirstOrDefault(x => x.AcademicPlanId == model.AcademicPlanId && x.YearEntrance == model.YearEntrance && x.GroupNumber == model.GroupNumber && x.Id != model.Id);
protected override IQueryable<StudentGroup> IncludingWhenReading(IQueryable<StudentGroup> query) => query.Include(x => x.EducationDirection).Include(x => x.Lecturer).Include(x => x.Students);
protected override IQueryable<StudentGroup> IncludingWhenReading(IQueryable<StudentGroup> query) => query.Include(x => x.AcademicPlan).Include(x => x.AcademicPlan.EducationDirection).Include(x => x.Lecturer).Include(x => x.Students);
protected override IQueryable<StudentGroup> OrderingWhenReading(IQueryable<StudentGroup> query) => query.OrderBy(x => x.EducationDirection.Cipher).ThenBy(x => x.AcademicCourse).ThenBy(x => x.GroupNumber);
protected override IQueryable<StudentGroup> OrderingWhenReading(IQueryable<StudentGroup> query) => query.OrderBy(x => x.AcademicPlan.EducationDirection.Qualification).ThenBy(x => x.AcademicPlan.EducationDirection.Cipher).ThenBy(x => x.YearEntrance).ThenBy(x => x.GroupNumber);
}
}

View File

@ -32,10 +32,6 @@ namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntit
{
query = query.Where(x => x.StudentGroupId == model.StudentGroupId.Value);
}
if (model.EnrollmentYearId.HasValue)
{
query = query.Where(x => x.EnrollmentYearId == model.EnrollmentYearId.Value);
}
if (model.StudentState.HasValue)
{
query = query.Where(x => x.StudentState == model.StudentState.Value);
@ -64,7 +60,7 @@ namespace DepartmentDatabaseImplementation.Implementations.AbstractGenerticEntit
protected override IQueryable<Student> IncludingWhenReading(IQueryable<Student> query) => query.Include(x => x.StudentGroup).Include(x => x.User);
protected override IQueryable<Student> OrderingWhenReading(IQueryable<Student> query) => query.OrderBy(x => x.StudentGroup.AcademicCourse).ThenBy(x => x.StudentGroup.GroupNumber).ThenBy(x => x.LastName).ThenBy(x => x.FirstName);
protected override IQueryable<Student> OrderingWhenReading(IQueryable<Student> query) => query.OrderBy(x => x.StudentGroup.YearEntrance).ThenBy(x => x.StudentGroup.GroupNumber).ThenBy(x => x.LastName).ThenBy(x => x.FirstName);
protected override bool AdditionalCheckForSingleGet(StudentGetBindingModel model)
{

View File

@ -1,33 +0,0 @@

namespace DepartmentWindowsDesktop.EntityControls
{
partial class ControlEnrollmentYearElement
{
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
}
#endregion
}
}

View File

@ -1,30 +0,0 @@
using DepartmentContract.BindingModels;
using DepartmentContract.Logics.IGenericEntityLogic;
using DepartmentContract.ViewModels;
using System;
using ToolsDesktop.Controls;
using ToolsDesktop.Interfaces;
using ToolsDesktop.Models;
namespace DepartmentWindowsDesktop.EntityControls
{
/// <summary>
/// Реализация контрола для года поступления
/// </summary>
public partial class ControlEnrollmentYearElement :
GenericControlEntityElement<EnrollmentYearGetBindingModel, EnrollmentYearSetBindingModel, EnrollmentYearListViewModel, EnrollmentYearViewModel, IEnrollmentYearLogic>,
IGenericControlEntityElement
{
public ControlEnrollmentYearElement()
{
InitializeComponent();
Title = "Год поступления";
ControlId = new Guid("363636d3-b3d0-4374-a573-2bcc78ca4eea");
_genericControlViewEntityElement = this;
}
public IControl GetInstanceGenericControl() => new ControlEnrollmentYearElement() { ControlId = Guid.NewGuid() };
public ControlViewEntityElementConfiguration GetConfigControl() => new();
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,33 +0,0 @@

namespace DepartmentWindowsDesktop.EntityControls
{
partial class ControlEnrollmentYearList
{
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
}
#endregion
}
}

View File

@ -1,42 +0,0 @@
using DepartmentContract.BindingModels;
using DepartmentContract.Logics.IGenericEntityLogic;
using DepartmentContract.ViewModels;
using System;
using System.Collections.Generic;
using ToolsDesktop.Controls;
using ToolsDesktop.Enums;
using ToolsDesktop.Interfaces;
using ToolsDesktop.Models;
using ToolsModule.ManagmentSecurity;
namespace DepartmentWindowsDesktop.EntityControls
{
/// <summary>
/// Реализация контрола для списка годов поступления
/// </summary>
public partial class ControlEnrollmentYearList :
GenericControlEntityList<EnrollmentYearGetBindingModel, EnrollmentYearSetBindingModel, EnrollmentYearListViewModel, EnrollmentYearViewModel, IEnrollmentYearLogic>,
IGenericControlEntityList
{
public ControlEnrollmentYearList()
{
InitializeComponent();
Title = "Года поступления";
ControlId = new Guid("c0b26e65-78fa-40b6-b6ab-2f9c5a0b19dc");
AccessOperation = AccessOperation.Должности;
ControlViewEntityElement = new ControlEnrollmentYearElement();
_genericControlViewEntityList = this;
}
public IControl GetInstanceGenericControl() => new ControlEnrollmentYearList() { ControlId = Guid.NewGuid() };
public ControlViewEntityListConfiguration GetConfigControl() => new()
{
PaginationOn = false,
HideToolStripButton = new List<ToolStripButtonListNames>
{
ToolStripButtonListNames.toolStripButtonSearch
}
};
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,30 @@
USE [DepartmentDatabasePortal]
GO
DELETE FROM [dbo].[OrderSyncHistories]
GO
DELETE FROM [dbo].[Orders]
GO
DELETE FROM [dbo].[Students]
GO
DELETE FROM [dbo].[StudentGroups]
GO
DECLARE @RoleId uniqueidentifier
SELECT @RoleId = [Id]
FROM [dbo].[Roles]
WHERE [RoleName] = 'Ñòóäåíò'
DELETE u FROM [dbo].[Users] u
JOIN [dbo].[UserRoles] ur ON u.[Id] = ur.[UserId]
WHERE ur.[RoleId] = @RoleId
DELETE FROM [dbo].[UserRoles]
WHERE [RoleId] = @RoleId
GO