добавлены группы

This commit is contained in:
kotcheshir73 2021-04-12 10:01:42 +04:00
parent 4008a5e2a5
commit d5319759e2
28 changed files with 1969 additions and 11 deletions

View File

@ -57,6 +57,8 @@ namespace DatabaseCore
modelBuilder.Entity<AcademicPlanRecord>().HasIndex(d => new { d.AcademicPlanId, d.DisciplineId, d.Semester }).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<AcademicPlanRecordTimeNormHour>().HasIndex(d => new { d.AcademicPlanRecordId, d.TimeNormId }).IsUnique();
modelBuilder.Entity<StudentGroup>().HasIndex(d => new { d.AcademicPlanId, d.EnrollmentYear, d.GroupNumber }).IsUnique();
} }
#region Security #region Security
@ -83,6 +85,7 @@ namespace DatabaseCore
public virtual DbSet<AcademicPlan> AcademicPlans { set; get; } public virtual DbSet<AcademicPlan> AcademicPlans { set; get; }
public virtual DbSet<AcademicPlanRecord> AcademicPlanRecords { set; get; } public virtual DbSet<AcademicPlanRecord> AcademicPlanRecords { set; get; }
public virtual DbSet<AcademicPlanRecordTimeNormHour> AcademicPlanRecordTimeNormHours { set; get; } public virtual DbSet<AcademicPlanRecordTimeNormHour> AcademicPlanRecordTimeNormHours { set; get; }
public virtual DbSet<StudentGroup> StudentGroups { set; get; }
#endregion #endregion
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace DatabaseCore.Migrations
{
public partial class AddStudentGroups : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_AcademicPlanRecordTimeNormHours_TimeNorms_TimeNormId",
table: "AcademicPlanRecordTimeNormHours");
migrationBuilder.CreateTable(
name: "StudentGroups",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
AcademicPlanId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
GroupNumber = table.Column<int>(type: "int", nullable: false),
EnrollmentYear = table.Column<int>(type: "int", nullable: false),
LecturerId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false),
DateDelete = table.Column<DateTime>(type: "datetime2", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_StudentGroups", x => x.Id);
table.ForeignKey(
name: "FK_StudentGroups_AcademicPlans_AcademicPlanId",
column: x => x.AcademicPlanId,
principalTable: "AcademicPlans",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_StudentGroups_Lecturers_LecturerId",
column: x => x.LecturerId,
principalTable: "Lecturers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_StudentGroups_AcademicPlanId_EnrollmentYear_GroupNumber",
table: "StudentGroups",
columns: new[] { "AcademicPlanId", "EnrollmentYear", "GroupNumber" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_StudentGroups_LecturerId",
table: "StudentGroups",
column: "LecturerId");
migrationBuilder.AddForeignKey(
name: "FK_AcademicPlanRecordTimeNormHours_TimeNorms_TimeNormId",
table: "AcademicPlanRecordTimeNormHours",
column: "TimeNormId",
principalTable: "TimeNorms",
principalColumn: "Id",
onDelete: ReferentialAction.NoAction);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_AcademicPlanRecordTimeNormHours_TimeNorms_TimeNormId",
table: "AcademicPlanRecordTimeNormHours");
migrationBuilder.DropTable(
name: "StudentGroups");
migrationBuilder.AddForeignKey(
name: "FK_AcademicPlanRecordTimeNormHours_TimeNorms_TimeNormId",
table: "AcademicPlanRecordTimeNormHours",
column: "TimeNormId",
principalTable: "TimeNorms",
principalColumn: "Id");
}
}
}

View File

@ -623,6 +623,42 @@ namespace DatabaseCore.Migrations
b.ToTable("Posts"); b.ToTable("Posts");
}); });
modelBuilder.Entity("DatabaseCore.Models.Department.StudentGroup", 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<int>("EnrollmentYear")
.HasColumnType("int");
b.Property<int>("GroupNumber")
.HasColumnType("int");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<Guid?>("LecturerId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("LecturerId");
b.HasIndex("AcademicPlanId", "EnrollmentYear", "GroupNumber")
.IsUnique();
b.ToTable("StudentGroups");
});
modelBuilder.Entity("DatabaseCore.Models.Department.TimeNorm", b => modelBuilder.Entity("DatabaseCore.Models.Department.TimeNorm", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
@ -1003,6 +1039,23 @@ namespace DatabaseCore.Migrations
b.Navigation("Post"); b.Navigation("Post");
}); });
modelBuilder.Entity("DatabaseCore.Models.Department.StudentGroup", b =>
{
b.HasOne("DatabaseCore.Models.Department.AcademicPlan", "AcademicPlan")
.WithMany("StudentGroups")
.HasForeignKey("AcademicPlanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DatabaseCore.Models.Department.Lecturer", "Lecturer")
.WithMany("StudentGroups")
.HasForeignKey("LecturerId");
b.Navigation("AcademicPlan");
b.Navigation("Lecturer");
});
modelBuilder.Entity("DatabaseCore.Models.Department.TimeNorm", b => modelBuilder.Entity("DatabaseCore.Models.Department.TimeNorm", b =>
{ {
b.HasOne("DatabaseCore.Models.Department.DisciplineBlock", "DisciplineBlock") b.HasOne("DatabaseCore.Models.Department.DisciplineBlock", "DisciplineBlock")
@ -1047,6 +1100,8 @@ namespace DatabaseCore.Migrations
modelBuilder.Entity("DatabaseCore.Models.Department.AcademicPlan", b => modelBuilder.Entity("DatabaseCore.Models.Department.AcademicPlan", b =>
{ {
b.Navigation("AcademicPlanRecords"); b.Navigation("AcademicPlanRecords");
b.Navigation("StudentGroups");
}); });
modelBuilder.Entity("DatabaseCore.Models.Department.AcademicPlanRecord", b => modelBuilder.Entity("DatabaseCore.Models.Department.AcademicPlanRecord", b =>
@ -1083,6 +1138,8 @@ namespace DatabaseCore.Migrations
b.Navigation("EducationDirections"); b.Navigation("EducationDirections");
b.Navigation("LecturerPosts"); b.Navigation("LecturerPosts");
b.Navigation("StudentGroups");
}); });
modelBuilder.Entity("DatabaseCore.Models.Department.LecturerAcademicDegree", b => modelBuilder.Entity("DatabaseCore.Models.Department.LecturerAcademicDegree", b =>

View File

@ -39,6 +39,9 @@ namespace DatabaseCore.Models.Department
[ForeignKey("AcademicPlanId")] [ForeignKey("AcademicPlanId")]
public virtual List<AcademicPlanRecord> AcademicPlanRecords { get; set; } 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 AcademicPlan SecurityCheck(AcademicPlan entity, bool allowFullData) => entity;

View File

@ -106,6 +106,9 @@ namespace DatabaseCore.Models.Department
[ForeignKey("LecturerId")] [ForeignKey("LecturerId")]
public virtual List<EducationDirection> EducationDirections { get; set; } public virtual List<EducationDirection> EducationDirections { get; set; }
[ForeignKey("LecturerId")]
public virtual List<StudentGroup> StudentGroups { get; set; }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
public Lecturer SecurityCheck(Lecturer entity, bool allowFullData) public Lecturer SecurityCheck(Lecturer entity, bool allowFullData)

View File

@ -0,0 +1,49 @@
using ModuleTools.Attributes;
using ModuleTools.Interfaces;
using System;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace DatabaseCore.Models.Department
{
/// <summary>
/// Класс, описывающий учебную группу кафедры
/// </summary>
[DataContract]
[EntityDescription("StudentGroup", "Учебная группа кафедры")]
[EntityDependency("AcademicPlan", "AcademicPlanId", "Учебный план, по которму учится группа")]
[EntityDependency("Lecturer", "LecturerId", "Куратор группы")]
public class StudentGroup : BaseEntity, IEntitySecurityExtenstion<StudentGroup>
{
[DataMember]
[Required(ErrorMessage = "required")]
[MapConfiguration("AcademicPlanId")]
public Guid AcademicPlanId { get; set; }
[DataMember]
[Required(ErrorMessage = "required")]
[MapConfiguration("GroupNumber")]
public int GroupNumber { get; set; }
[DataMember]
[Required(ErrorMessage = "required")]
[MapConfiguration("EnrollmentYear")]
public int EnrollmentYear { get; set; }
[DataMember]
[MapConfiguration("LecturerId")]
public Guid? LecturerId { get; set; }
//-------------------------------------------------------------------------
public virtual AcademicPlan AcademicPlan { get; set; }
public virtual Lecturer Lecturer { get; set; }
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
public StudentGroup SecurityCheck(StudentGroup entity, bool allowFullData) => entity;
}
}

View File

@ -18,7 +18,7 @@ namespace DesktopTools.BaseControls
/// <param name="minValue"></param> /// <param name="minValue"></param>
/// <param name="maxValue"></param> /// <param name="maxValue"></param>
/// <param name="decimalPlaces"></param> /// <param name="decimalPlaces"></param>
public BaseControlDecimal(string propertyName, bool mustFilling, bool readOnly, decimal minValue, decimal maxValue, int decimalPlaces) : base(propertyName, mustFilling, readOnly) public BaseControlDecimal(string propertyName, bool mustFilling, bool readOnly, double minValue, double maxValue, int decimalPlaces) : base(propertyName, mustFilling, readOnly)
{ {
InitializeComponent(); InitializeComponent();
_baseControl = this; _baseControl = this;
@ -26,11 +26,11 @@ namespace DesktopTools.BaseControls
numericUpDown.ValueChanged += (object sender, EventArgs e) => { CallOnValueChangeEvent(); }; numericUpDown.ValueChanged += (object sender, EventArgs e) => { CallOnValueChangeEvent(); };
if (minValue != 0) if (minValue != 0)
{ {
numericUpDown.Minimum = minValue; numericUpDown.Minimum = (decimal)minValue;
} }
if (maxValue != 0) if (maxValue != 0)
{ {
numericUpDown.Maximum = maxValue; numericUpDown.Maximum = (decimal)maxValue;
} }
if (decimalPlaces != 0) if (decimalPlaces != 0)
{ {

View File

@ -17,7 +17,7 @@ namespace DesktopTools.BaseControls
/// <param name="readOnly"></param> /// <param name="readOnly"></param>
/// <param name="minValue"></param> /// <param name="minValue"></param>
/// <param name="maxValue"></param> /// <param name="maxValue"></param>
public BaseControlInt(string propertyName, bool mustFilling, bool readOnly, decimal minValue, decimal maxValue) : base(propertyName, mustFilling, readOnly) public BaseControlInt(string propertyName, bool mustFilling, bool readOnly, double minValue, double maxValue) : base(propertyName, mustFilling, readOnly)
{ {
InitializeComponent(); InitializeComponent();
_baseControl = this; _baseControl = this;
@ -25,11 +25,11 @@ namespace DesktopTools.BaseControls
numericUpDown.ValueChanged += (object sender, EventArgs e) => { CallOnValueChangeEvent(); }; numericUpDown.ValueChanged += (object sender, EventArgs e) => { CallOnValueChangeEvent(); };
if (minValue != 0) if (minValue != 0)
{ {
numericUpDown.Minimum = minValue; numericUpDown.Minimum = (decimal)minValue;
} }
if (maxValue != 0) if (maxValue != 0)
{ {
numericUpDown.Maximum = maxValue; numericUpDown.Maximum = (decimal)maxValue;
} }
panelControl.Controls.Add(numericUpDown); panelControl.Controls.Add(numericUpDown);

View File

@ -48,12 +48,12 @@ namespace ModuleTools.Attributes
/// <summary> /// <summary>
/// Минимальное значение для числового параметра /// Минимальное значение для числового параметра
/// </summary> /// </summary>
public decimal MinValue { get; set; } = 0; public double MinValue { get; set; } = 0;
/// <summary> /// <summary>
/// Максимальное значение для числового параметра /// Максимальное значение для числового параметра
/// </summary> /// </summary>
public decimal MaxValue { get; set; } = 0; public double MaxValue { get; set; } = 0;
/// <summary> /// <summary>
/// Количество знаков после запятой /// Количество знаков после запятой

View File

@ -42,7 +42,7 @@
УчебныеПланы = 108, УчебныеПланы = 108,
Группы = 105, // УчебныеГруппы = 109,
Студенты = 106, Студенты = 106,

View File

@ -0,0 +1,38 @@
using ModuleTools.Attributes;
using ModuleTools.BindingModels;
using System;
using System.ComponentModel.DataAnnotations;
namespace DepartmentBusinessLogic.BindingModels
{
/// <summary>
/// Получение студенческой группы
/// </summary>
public class StudentGroupGetBindingModel : GetBindingModel
{
public Guid? AcademicPlanId { get; set; }
public Guid? LecturerId { get; set; }
}
/// <summary>
/// Сохранение студенческой группы
/// </summary>
public class StudentGroupSetBindingModel : SetBindingModel
{
[Required(ErrorMessage = "required")]
[MapConfiguration("AcademicPlanId")]
public Guid AcademicPlanId { get; set; }
[Required(ErrorMessage = "required")]
[MapConfiguration("GroupNumber")]
public int GroupNumber { get; set; }
[Required(ErrorMessage = "required")]
[MapConfiguration("EnrollmentYear")]
public int EnrollmentYear { get; set; }
[MapConfiguration("LecturerId")]
public Guid? LecturerId { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using DepartmentBusinessLogic.BindingModels;
using DepartmentBusinessLogic.Interfaces;
using DepartmentBusinessLogic.ViewModels;
using ModuleTools.BusinessLogics;
using ModuleTools.Enums;
namespace DepartmentBusinessLogic.BusinessLogics
{
/// <summary>
/// Логика работы с учебными группами
/// </summary>
public class StudentGroupBusinessLogic : GenericBusinessLogic<StudentGroupGetBindingModel, StudentGroupSetBindingModel, StudentGroupListViewModel, StudentGroupViewModel>
{
public StudentGroupBusinessLogic(IStudentGroupService service) : base(service, "Учебные Группы", AccessOperation.УчебныеГруппы) { }
}
}

View File

@ -0,0 +1,10 @@
using DepartmentBusinessLogic.BindingModels;
using ModuleTools.Interfaces;
namespace DepartmentBusinessLogic.Interfaces
{
/// <summary>
/// Хранение учебных групп
/// </summary>
public interface IStudentGroupService : IGenerticEntityService<StudentGroupGetBindingModel, StudentGroupSetBindingModel> { }
}

View File

@ -16,6 +16,8 @@ namespace DepartmentBusinessLogic.ViewModels
[ViewModelControlElementClass(HaveDependenceEntities = true, Width = 1200, Height = 800)] [ViewModelControlElementClass(HaveDependenceEntities = true, Width = 1200, Height = 800)]
[ViewModelControlElementDependenceEntity(Title = "Записи плана", Order = 1, ParentPropertyName = "AcademicPlanId", [ViewModelControlElementDependenceEntity(Title = "Записи плана", Order = 1, ParentPropertyName = "AcademicPlanId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlAcademicPlanRecordList, DepartmentWindowsDesktop")] ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlAcademicPlanRecordList, DepartmentWindowsDesktop")]
[ViewModelControlElementDependenceEntity(Title = "Группы", Order = 2, ParentPropertyName = "AcademicPlanId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlStudentGroupList, DepartmentWindowsDesktop")]
public class AcademicPlanViewModel : ElementViewModel public class AcademicPlanViewModel : ElementViewModel
{ {
[ViewModelControlElementProperty("Направление", ControlType.ControlGuid, MustHaveValue = false, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlEducationDirectionList, DepartmentWindowsDesktop")] [ViewModelControlElementProperty("Направление", ControlType.ControlGuid, MustHaveValue = false, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlEducationDirectionList, DepartmentWindowsDesktop")]
@ -26,6 +28,10 @@ namespace DepartmentBusinessLogic.ViewModels
[MapConfiguration("EducationDirection.Cipher", IsDifficle = true)] [MapConfiguration("EducationDirection.Cipher", IsDifficle = true)]
public string EducationDirectionCipher { get; set; } public string EducationDirectionCipher { get; set; }
[ViewModelControlListProperty("Профиль")]
[MapConfiguration("EducationDirection.Profile", IsDifficle = true)]
public string EducationDirectionProfile { get; set; }
[ViewModelControlListProperty("Дата начала", ColumnWidth = 120)] [ViewModelControlListProperty("Дата начала", ColumnWidth = 120)]
[ViewModelControlElementProperty("Дата начала", ControlType.ControlInt, MustHaveValue = true)] [ViewModelControlElementProperty("Дата начала", ControlType.ControlInt, MustHaveValue = true)]
[MapConfiguration("YearEntrance")] [MapConfiguration("YearEntrance")]

View File

@ -19,6 +19,8 @@ namespace DepartmentBusinessLogic.ViewModels
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlLecturerPostList, DepartmentWindowsDesktop")] ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlLecturerPostList, DepartmentWindowsDesktop")]
[ViewModelControlElementDependenceEntity(Title = "Напрвления обучения", Order = 2, ParentPropertyName = "LecturerId", [ViewModelControlElementDependenceEntity(Title = "Напрвления обучения", Order = 2, ParentPropertyName = "LecturerId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlEducationDirectionList, DepartmentWindowsDesktop")] ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlEducationDirectionList, DepartmentWindowsDesktop")]
[ViewModelControlElementDependenceEntity(Title = "Кураторство групп", Order = 3, ParentPropertyName = "LecturerId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlStudentGroupList, DepartmentWindowsDesktop")]
public class LecturerViewModel : ElementViewModel public class LecturerViewModel : ElementViewModel
{ {
[ViewModelControlElementProperty("Пользователь", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlUserList, SecurityWindowsDesktop")] [ViewModelControlElementProperty("Пользователь", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlUserList, SecurityWindowsDesktop")]

View File

@ -0,0 +1,61 @@
using ModuleTools.Attributes;
using ModuleTools.Enums;
using ModuleTools.Extensions;
using ModuleTools.ViewModels;
using System;
namespace DepartmentBusinessLogic.ViewModels
{
/// <summary>
/// Список дисциплин
/// </summary>
public class StudentGroupListViewModel : ListViewModel<StudentGroupViewModel> { }
/// <summary>
/// Элемент дисциплина
/// </summary>
[ViewModelControlElementClass(HaveDependenceEntities = true, Width = 800, Height = 500)]
//[ViewModelControlElementDependenceEntity(Title = "Записи учебного плана", Order = 1, ParentPropertyName = "DisciplineId",
// ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlAcademicPlanRecordList, DepartmentWindowsDesktop")]
public class StudentGroupViewModel : ElementViewModel
{
[ViewModelControlElementProperty("Учебный план", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlAcademicPlanList, DepartmentWindowsDesktop")]
[MapConfiguration("AcademicPlanId")]
public Guid AcademicPlanId { get; set; }
[ViewModelControlListProperty("Шифр")]
[MapConfiguration("AcademicPlan.EducationDirection.Cipher", IsDifficle = true)]
public string AcademicPlanEducationDirectionCipher { get; set; }
[MapConfiguration("AcademicPlan.EducationDirection.ShortName", IsDifficle = true)]
public string AcademicPlanEducationDirectionShortName { get; set; }
[ViewModelControlListProperty("Номер группы")]
[ViewModelControlElementProperty("Номер группы", ControlType.ControlInt, MustHaveValue = true, MinValue = 1, MaxValue = 4)]
[MapConfiguration("GroupNumber")]
public int GroupNumber { get; set; }
[ViewModelControlListProperty("Год зачисления")]
[ViewModelControlElementProperty("Год зачисления", ControlType.ControlInt, MustHaveValue = true)]
[MapConfiguration("EnrollmentYear")]
public int EnrollmentYear { get; set; }
[ViewModelControlElementProperty("Куратор", ControlType.ControlGuid, MustHaveValue = false, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlLecturerList, DepartmentWindowsDesktop")]
[MapConfiguration("LecturerId")]
public Guid? CuratorId { get; set; }
[MapConfiguration("Lecturer.LastName", IsDifficle = true)]
public string LecturerLastName { get; set; }
[MapConfiguration("Lecturer.FirstName", IsDifficle = true)]
public string LecturerFirstName { get; set; }
[MapConfiguration("Lecturer.Patronymic", IsDifficle = true)]
public string LecturerPatronymic { get; set; }
[ViewModelControlListProperty("Куратор")]
public string Lecturer => $"{LecturerLastName}{(LecturerFirstName.IsNotEmpty() ? $" {LecturerFirstName[0]}." : string.Empty)}{(LecturerPatronymic.IsNotEmpty() ? $"{LecturerPatronymic[0]}." : string.Empty)}";
public override string ToString() => $"{AcademicPlanEducationDirectionShortName}-{GroupNumber}";
}
}

View File

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

View File

@ -27,7 +27,14 @@ namespace DepartmentDatabaseImplementation.Implementations
{ {
protected override OperationResultModel AdditionalCheckingWhenAdding(DbContext context, AcademicPlanSetBindingModel model) => OperationResultModel.Success(null); 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.IsDeleted))
{
return OperationResultModel.Error("Error:", "Есть учебные группы, относящиеся к этому учебному плану", ResultServiceStatusCode.ExsistItem);
}
return OperationResultModel.Success(null);
}
protected override IQueryable<AcademicPlan> AdditionalCheckingWhenReadingList(IQueryable<AcademicPlan> query, AcademicPlanGetBindingModel model) protected override IQueryable<AcademicPlan> AdditionalCheckingWhenReadingList(IQueryable<AcademicPlan> query, AcademicPlanGetBindingModel model)
{ {

View File

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

View File

@ -0,0 +1,50 @@
using DatabaseCore;
using DatabaseCore.Models.Department;
using DepartmentBusinessLogic.BindingModels;
using DepartmentBusinessLogic.Interfaces;
using DepartmentBusinessLogic.ViewModels;
using Microsoft.EntityFrameworkCore;
using ModuleTools.Models;
using System.Linq;
namespace DepartmentDatabaseImplementation.Implementations
{
/// <summary>
/// Реализация IStudentGroupService
/// </summary>
public class StudentGroupService :
AbstractGenerticEntityService<StudentGroupGetBindingModel, StudentGroupSetBindingModel, StudentGroup, StudentGroupListViewModel, StudentGroupViewModel>,
IStudentGroupService
{
protected override OperationResultModel AdditionalCheckingWhenAdding(DbContext context, StudentGroupSetBindingModel model) => OperationResultModel.Success(null);
protected override OperationResultModel AdditionalCheckingWhenDeleting(DbContext context, StudentGroup entity, StudentGroupGetBindingModel model)
{
return OperationResultModel.Success(null);
}
protected override IQueryable<StudentGroup> AdditionalCheckingWhenReadingList(IQueryable<StudentGroup> query, StudentGroupGetBindingModel model)
{
if (model.AcademicPlanId.HasValue)
{
query = query.Where(x => x.AcademicPlanId == model.AcademicPlanId.Value);
}
if (model.LecturerId.HasValue)
{
query = query.Where(x => x.LecturerId == model.LecturerId.Value);
}
return query;
}
protected override OperationResultModel AdditionalCheckingWhenUpdateing(DbContext context, StudentGroupSetBindingModel model) => OperationResultModel.Success(null);
protected override void AdditionalDeleting(DbContext context, StudentGroup entity, StudentGroupGetBindingModel model) { }
protected override StudentGroup GetUniqueEntity(StudentGroupSetBindingModel model, DbContext context) => context.Set<StudentGroup>().FirstOrDefault(x => x.AcademicPlanId == model.AcademicPlanId && x.EnrollmentYear == model.EnrollmentYear && x.GroupNumber == model.GroupNumber && x.Id != model.Id);
protected override IQueryable<StudentGroup> IncludingWhenReading(IQueryable<StudentGroup> query) => query.Include(x => x.AcademicPlan).Include(x => x.Lecturer);
protected override IQueryable<StudentGroup> OrderingWhenReading(IQueryable<StudentGroup> query) => query.OrderBy(x => x.EnrollmentYear).ThenBy(x => x.GroupNumber);
}
}

View File

@ -42,7 +42,8 @@ namespace DepartmentWindowsDesktop
new ControlLecturerList(), new ControlLecturerList(),
new ControlEducationDirectionList(), new ControlEducationDirectionList(),
new ControlTimeNormList(), new ControlTimeNormList(),
new ControlAcademicPlanList() new ControlAcademicPlanList(),
new ControlStudentGroupList()
}; };
foreach (var cntrl in _controls) foreach (var cntrl in _controls)

View File

@ -0,0 +1,33 @@

namespace DepartmentWindowsDesktop.EntityControls
{
partial class ControlStudentGroupElement
{
/// <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

@ -0,0 +1,30 @@
using DepartmentBusinessLogic.BindingModels;
using DepartmentBusinessLogic.BusinessLogics;
using DepartmentBusinessLogic.ViewModels;
using DesktopTools.Controls;
using DesktopTools.Interfaces;
using DesktopTools.Models;
using System;
namespace DepartmentWindowsDesktop.EntityControls
{
/// <summary>
/// Реализация контрола для учебной группы
/// </summary>
public partial class ControlStudentGroupElement :
GenericControlEntityElement<StudentGroupGetBindingModel, StudentGroupSetBindingModel, StudentGroupListViewModel, StudentGroupViewModel, StudentGroupBusinessLogic>,
IGenericControlEntityElement
{
public ControlStudentGroupElement()
{
InitializeComponent();
Title = "Учебная группа";
ControlId = new Guid("949d6004-b10e-4e9b-8cc4-21a7c31e599a");
_genericControlViewEntityElement = this;
}
public IControl GetInstanceGenericControl() => new ControlStudentGroupElement() { ControlId = Guid.NewGuid() };
public ControlViewEntityElementConfiguration GetConfigControl() => new();
}
}

View File

@ -0,0 +1,120 @@
<?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,33 @@

namespace DepartmentWindowsDesktop.EntityControls
{
partial class ControlStudentGroupList
{
/// <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

@ -0,0 +1,42 @@
using DepartmentBusinessLogic.BindingModels;
using DepartmentBusinessLogic.BusinessLogics;
using DepartmentBusinessLogic.ViewModels;
using DesktopTools.Controls;
using DesktopTools.Enums;
using DesktopTools.Interfaces;
using DesktopTools.Models;
using ModuleTools.Enums;
using System;
using System.Collections.Generic;
namespace DepartmentWindowsDesktop.EntityControls
{
/// <summary>
/// Реализация контрола для списка учебных групп
/// </summary>
public partial class ControlStudentGroupList :
GenericControlEntityList<StudentGroupGetBindingModel, StudentGroupSetBindingModel, StudentGroupListViewModel, StudentGroupViewModel, StudentGroupBusinessLogic>,
IGenericControlEntityList
{
public ControlStudentGroupList()
{
InitializeComponent();
Title = "Учебные группы";
ControlId = new Guid("453666ff-511e-4751-887f-0fec5c1e95c8");
AccessOperation = AccessOperation.УчебныеГруппы;
ControlViewEntityElement = new ControlStudentGroupElement();
_genericControlViewEntityList = this;
}
public IControl GetInstanceGenericControl() => new ControlStudentGroupList() { ControlId = Guid.NewGuid() };
public ControlViewEntityListConfiguration GetConfigControl() => new()
{
PaginationOn = false,
HideToolStripButton = new List<ToolStripButtonListNames>
{
ToolStripButtonListNames.toolStripButtonSearch
}
};
}
}

View File

@ -0,0 +1,120 @@
<?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>