студенты

This commit is contained in:
kotcheshir73 2021-04-12 16:57:29 +04:00
parent 11cb574c3a
commit 301854f284
28 changed files with 2284 additions and 11 deletions

View File

@ -100,7 +100,7 @@ namespace DatabaseCore
// для одной записи
if (model.Id.HasValue)
{
var entity = context.Set<T>().FirstOrDefault(x => x.Id == model.Id.Value);
var entity = IncludingWhenReading(context.Set<T>().AsQueryable()).FirstOrDefault(x => x.Id == model.Id.Value);
if (entity == null)
{
return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);

View File

@ -59,6 +59,8 @@ namespace DatabaseCore
modelBuilder.Entity<AcademicPlanRecordTimeNormHour>().HasIndex(d => new { d.AcademicPlanRecordId, d.TimeNormId }).IsUnique();
modelBuilder.Entity<StudentGroup>().HasIndex(d => new { d.AcademicPlanId, d.EnrollmentYear, d.GroupNumber }).IsUnique();
modelBuilder.Entity<Student>().HasIndex(d => new { d.NumberOfBook }).IsUnique();
}
#region Security
@ -86,6 +88,7 @@ namespace DatabaseCore
public virtual DbSet<AcademicPlanRecord> AcademicPlanRecords { set; get; }
public virtual DbSet<AcademicPlanRecordTimeNormHour> AcademicPlanRecordTimeNormHours { set; get; }
public virtual DbSet<StudentGroup> StudentGroups { set; get; }
public virtual DbSet<Student> Students { set; get; }
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace DatabaseCore.Migrations
{
public partial class AddStudents : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Students",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
StudentGroupId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
NumberOfBook = table.Column<string>(type: "nvarchar(450)", nullable: false),
LastName = table.Column<string>(type: "nvarchar(max)", nullable: false),
FirstName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Patronymic = table.Column<string>(type: "nvarchar(max)", nullable: true),
Email = table.Column<string>(type: "nvarchar(max)", nullable: false),
Description = table.Column<string>(type: "nvarchar(max)", nullable: true),
StudentState = table.Column<int>(type: "int", nullable: false),
Photo = table.Column<byte[]>(type: "varbinary(max)", nullable: true),
IsSteward = table.Column<bool>(type: "bit", 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)
},
constraints: table =>
{
table.PrimaryKey("PK_Students", x => x.Id);
table.ForeignKey(
name: "FK_Students_StudentGroups_StudentGroupId",
column: x => x.StudentGroupId,
principalTable: "StudentGroups",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Students_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Students_NumberOfBook",
table: "Students",
column: "NumberOfBook",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Students_StudentGroupId",
table: "Students",
column: "StudentGroupId");
migrationBuilder.CreateIndex(
name: "IX_Students_UserId",
table: "Students",
column: "UserId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Students");
}
}
}

View File

@ -623,6 +623,69 @@ namespace DatabaseCore.Migrations
b.ToTable("Posts");
});
modelBuilder.Entity("DatabaseCore.Models.Department.Student", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateDelete")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<bool>("IsSteward")
.HasColumnType("bit");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("NumberOfBook")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<string>("Patronymic")
.HasColumnType("nvarchar(max)");
b.Property<byte[]>("Photo")
.HasColumnType("varbinary(max)");
b.Property<Guid>("StudentGroupId")
.HasColumnType("uniqueidentifier");
b.Property<int>("StudentState")
.HasColumnType("int");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("NumberOfBook")
.IsUnique();
b.HasIndex("StudentGroupId");
b.HasIndex("UserId");
b.ToTable("Students");
});
modelBuilder.Entity("DatabaseCore.Models.Department.StudentGroup", b =>
{
b.Property<Guid>("Id")
@ -1039,6 +1102,25 @@ namespace DatabaseCore.Migrations
b.Navigation("Post");
});
modelBuilder.Entity("DatabaseCore.Models.Department.Student", b =>
{
b.HasOne("DatabaseCore.Models.Department.StudentGroup", "StudentGroup")
.WithMany("Students")
.HasForeignKey("StudentGroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DatabaseCore.Models.Security.User", "User")
.WithMany("Students")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("StudentGroup");
b.Navigation("User");
});
modelBuilder.Entity("DatabaseCore.Models.Department.StudentGroup", b =>
{
b.HasOne("DatabaseCore.Models.Department.AcademicPlan", "AcademicPlan")
@ -1159,6 +1241,11 @@ namespace DatabaseCore.Migrations
b.Navigation("LecturerPosts");
});
modelBuilder.Entity("DatabaseCore.Models.Department.StudentGroup", b =>
{
b.Navigation("Students");
});
modelBuilder.Entity("DatabaseCore.Models.Department.TimeNorm", b =>
{
b.Navigation("AcademicPlanRecordTimeNormHours");
@ -1177,6 +1264,8 @@ namespace DatabaseCore.Migrations
b.Navigation("Lecturers");
b.Navigation("Students");
b.Navigation("UserRoles");
});
#pragma warning restore 612, 618

View File

@ -0,0 +1,91 @@
using DatabaseCore.Models.Security;
using ModuleTools.Attributes;
using ModuleTools.Interfaces;
using System;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace DatabaseCore.Models.Department
{
/// <summary>
/// Класс, описывающий студента кафедры
/// </summary>
[DataContract]
[EntityDescription("Student", "Студент кафедры")]
[EntityDependency("User", "UserId", "К какому пользователю относится студент")]
[EntityDependency("StudentGroup", "StudentGroupId", "К какой группе относится студент")]
public class Student : BaseEntity, IEntitySecurityExtenstion<Student>
{
[DataMember]
[Required]
[MapConfiguration("UserId")]
public Guid UserId { get; set; }
[DataMember]
[Required]
[MapConfiguration("StudentGroupId")]
public Guid StudentGroupId { get; set; }
[DataMember]
[Required]
[MapConfiguration("NumberOfBook")]
public string NumberOfBook { get; set; }
[DataMember]
[Required]
[MapConfiguration("LastName")]
public string LastName { get; set; }
[DataMember]
[Required]
[MapConfiguration("FirstName")]
public string FirstName { get; set; }
[DataMember]
[MapConfiguration("Patronymic")]
public string Patronymic { get; set; }
[DataMember]
[Required]
[MapConfiguration("Email")]
public string Email { get; set; }
[DataMember]
[MapConfiguration("Description")]
public string Description { get; set; }
[Required(ErrorMessage = "required")]
[MapConfiguration("StudentState")]
public int StudentState { get; set; }
[DataMember]
[MapConfiguration("Photo")]
public byte[] Photo { get; set; }
[DataMember]
[MapConfiguration("IsSteward")]
public bool IsSteward { get; set; }
//-------------------------------------------------------------------------
public virtual User User { get; set; }
public virtual StudentGroup StudentGroup { get; set; }
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
public Student SecurityCheck(Student entity, bool allowFullData)
{
if (!allowFullData)
{
entity.NumberOfBook = Guid.NewGuid().ToString();
entity.Email = "скрыто";
entity.Photo = null;
}
return entity;
}
}
}

View File

@ -1,7 +1,9 @@
using ModuleTools.Attributes;
using ModuleTools.Interfaces;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace DatabaseCore.Models.Department
@ -42,6 +44,9 @@ namespace DatabaseCore.Models.Department
//-------------------------------------------------------------------------
[ForeignKey("StudentGroupId")]
public virtual List<Student> Students { get; set; }
//-------------------------------------------------------------------------
public StudentGroup SecurityCheck(StudentGroup entity, bool allowFullData) => entity;

View File

@ -59,6 +59,9 @@ namespace DatabaseCore.Models.Security
[ForeignKey("UserId")]
public virtual List<Lecturer> Lecturers { get; set; }
[ForeignKey("UserId")]
public virtual List<Student> Students { get; set; }
//-------------------------------------------------------------------------
public User SecurityCheck(User entity, bool allowFullData)

View File

@ -44,7 +44,7 @@
УчебныеГруппы = 109,
Студенты = 106,
Студенты = 110,
Приказы_студентов = 107,
#endregion

View File

@ -0,0 +1,64 @@
using DepartmentBusinessLogic.Enums;
using ModuleTools.Attributes;
using ModuleTools.BindingModels;
using System;
using System.ComponentModel.DataAnnotations;
namespace DepartmentBusinessLogic.BindingModels
{
/// <summary>
/// Получение студента
/// </summary>
public class StudentGetBindingModel : GetBindingModel
{
public Guid? UserId { get; set; }
public Guid? StudentGroupId { get; set; }
public StudentState? StudentState { get; set; }
}
/// <summary>
/// Сохранение студента
/// </summary>
public class StudentSetBindingModel : SetBindingModel
{
[Required(ErrorMessage = "required")]
[MapConfiguration("UserId")]
public Guid UserId { get; set; }
[MapConfiguration("StudentGroupId")]
public Guid? StudentGroupId { get; set; }
[Required(ErrorMessage = "required")]
[MapConfiguration("NumberOfBook")]
public string NumberOfBook { get; set; }
[Required(ErrorMessage = "required")]
[MapConfiguration("FirstName")]
public string FirstName { get; set; }
[Required(ErrorMessage = "required")]
[MapConfiguration("LastName")]
public string LastName { get; set; }
[MapConfiguration("Patronymic")]
public string Patronymic { get; set; }
[MapConfiguration("Email")]
public string Email { get; set; }
[MapConfiguration("Description")]
public string Description { get; set; }
[Required(ErrorMessage = "required")]
[MapConfiguration("StudentState")]
public StudentState StudentState { get; set; }
[MapConfiguration("Photo")]
public byte[] Photo { get; set; }
[MapConfiguration("IsSteward")]
public bool IsSteward { 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 StudentBusinessLogic : GenericBusinessLogic<StudentGetBindingModel, StudentSetBindingModel, StudentListViewModel, StudentViewModel>
{
public StudentBusinessLogic(IStudentService service) : base(service, "Студенты", AccessOperation.Студенты) { }
}
}

View File

@ -0,0 +1,16 @@
namespace DepartmentBusinessLogic.Enums
{
/// <summary>
/// Статус студента
/// </summary>
public enum StudentState
{
Учится = 0,
Академ = 1,
Завершил = 2,
Отчислен = 3
}
}

View File

@ -0,0 +1,10 @@
using DepartmentBusinessLogic.BindingModels;
using ModuleTools.Interfaces;
namespace DepartmentBusinessLogic.Interfaces
{
/// <summary>
/// Хранение студентов
/// </summary>
public interface IStudentService : IGenerticEntityService<StudentGetBindingModel, StudentSetBindingModel> { }
}

View File

@ -7,29 +7,36 @@ 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")]
[ViewModelControlElementDependenceEntity(Title = "Студенты", Order = 1, ParentPropertyName = "StudentGroupId",
ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlStudentList, 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("Шифр")]
[ViewModelControlListProperty("Шифр", ColumnWidth = 80)]
[MapConfiguration("AcademicPlan.EducationDirection.Cipher", IsDifficle = true)]
public string AcademicPlanEducationDirectionCipher { get; set; }
[ViewModelControlListProperty("Профиль")]
[MapConfiguration("AcademicPlan.EducationDirection.Profile", IsDifficle = true)]
public string AcademicPlanEducationDirectionProfile { get; set; }
[MapConfiguration("AcademicPlan.EducationDirection.ShortName", IsDifficle = true)]
public string AcademicPlanEducationDirectionShortName { get; set; }
[ViewModelControlListProperty("Группа")]
public string GroupName => $"{AcademicPlanEducationDirectionShortName}({EnrollmentYear})-{GroupNumber}";
[ViewModelControlListProperty("Номер группы")]
[ViewModelControlElementProperty("Номер группы", ControlType.ControlInt, MustHaveValue = true, MinValue = 1, MaxValue = 4)]
[MapConfiguration("GroupNumber")]
@ -56,6 +63,6 @@ namespace DepartmentBusinessLogic.ViewModels
[ViewModelControlListProperty("Куратор")]
public string Lecturer => $"{LecturerLastName}{(LecturerFirstName.IsNotEmpty() ? $" {LecturerFirstName[0]}." : string.Empty)}{(LecturerPatronymic.IsNotEmpty() ? $"{LecturerPatronymic[0]}." : string.Empty)}";
public override string ToString() => $"{AcademicPlanEducationDirectionShortName}-{GroupNumber}";
public override string ToString() => GroupName;
}
}

View File

@ -0,0 +1,78 @@
using DepartmentBusinessLogic.Enums;
using ModuleTools.Attributes;
using ModuleTools.Enums;
using ModuleTools.Extensions;
using ModuleTools.ViewModels;
using System;
namespace DepartmentBusinessLogic.ViewModels
{
/// <summary>
/// Список студентов
/// </summary>
public class StudentListViewModel : ListViewModel<StudentViewModel> { }
/// <summary>
/// Элемент студент
/// </summary>
[ViewModelControlElementClass(HaveDependenceEntities = true, Width = 800, Height = 500)]
//[ViewModelControlElementDependenceEntity(Title = "Записи учебного плана", Order = 1, ParentPropertyName = "DisciplineId",
// ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlAcademicPlanRecordList, DepartmentWindowsDesktop")]
public class StudentViewModel : ElementViewModel
{
[ViewModelControlElementProperty("Пользователь", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlUserList, SecurityWindowsDesktop")]
[MapConfiguration("UserId")]
public Guid UserId { get; set; }
[ViewModelControlElementProperty("Группа", ControlType.ControlGuid, MustHaveValue = false, ReadOnly = false, ControlTypeObject = "DepartmentWindowsDesktop.EntityControls.ControlStudentGroupList, DepartmentWindowsDesktop")]
[MapConfiguration("StudentGroupId")]
public Guid? StudentGroupId { get; set; }
[ViewModelControlListProperty("Номер зачетки")]
[ViewModelControlElementProperty("Номер зачетки", ControlType.ControlString, MustHaveValue = true, ReadOnly = true)]
[MapConfiguration("NumberOfBook")]
public string NumberOfBook { get; set; }
[ViewModelControlListProperty("Фамилия")]
[ViewModelControlElementProperty("Фамилия", ControlType.ControlString, MustHaveValue = true)]
[MapConfiguration("LastName")]
public string LastName { get; set; }
[ViewModelControlListProperty("Имя")]
[ViewModelControlElementProperty("Имя", ControlType.ControlString, MustHaveValue = true)]
[MapConfiguration("FirstName")]
public string FirstName { get; set; }
[ViewModelControlListProperty("Отчество")]
[ViewModelControlElementProperty("Отчество", ControlType.ControlString, MustHaveValue = true)]
[MapConfiguration("Patronymic")]
public string Patronymic { get; set; }
[ViewModelControlListProperty("Эл. почта", ColumnWidth = 90)]
[ViewModelControlElementProperty("Эл. почта", ControlType.ControlString, MustHaveValue = true)]
[MapConfiguration("Email")]
public string Email { get; set; }
[ViewModelControlElementProperty("Описание", ControlType.ControlText)]
[MapConfiguration("Description")]
public string Description { get; set; }
[ViewModelControlElementProperty("Статус", ControlType.ControlEnum, MustHaveValue = true)]
[MapConfiguration("StudentState")]
public StudentState StudentState { get; set; }
[ViewModelControlListProperty("Статус", ColumnWidth = 90)]
public string StudentStateTitle => StudentState.ToString("G");
[ViewModelControlElementProperty("Фото", ControlType.ControlImage, Width = 200, Height = 200)]
[MapConfiguration("Photo")]
public byte[] Photo { get; set; }
[ViewModelControlElementProperty("Староста", ControlType.ControlBool, MustHaveValue = true)]
[MapConfiguration("IsSteward")]
public bool IsSteward { get; set; }
public override string ToString() =>
$"{LastName}{(FirstName.IsNotEmpty() ? $" {FirstName[0]}." : string.Empty)}{(Patronymic.IsNotEmpty() ? $"{Patronymic[0]}." : string.Empty)}";
}
}

View File

@ -33,6 +33,8 @@ namespace DepartmentDatabaseImplementation
DependencyManager.Instance.RegisterType<IAcademicPlanRecordTimeNormHourService, AcademicPlanRecordTimeNormHourService>();
DependencyManager.Instance.RegisterType<IStudentGroupService, StudentGroupService>();
DependencyManager.Instance.RegisterType<IStudentService, StudentService>();
}
}
}

View File

@ -4,6 +4,7 @@ using DepartmentBusinessLogic.BindingModels;
using DepartmentBusinessLogic.Interfaces;
using DepartmentBusinessLogic.ViewModels;
using Microsoft.EntityFrameworkCore;
using ModuleTools.Enums;
using ModuleTools.Models;
using System.Linq;
@ -20,7 +21,10 @@ namespace DepartmentDatabaseImplementation.Implementations
protected override OperationResultModel AdditionalCheckingWhenDeleting(DbContext context, StudentGroup entity, StudentGroupGetBindingModel model)
{
if (context.Set<Student>().Any(x => x.StudentGroupId == model.Id && !x.IsDeleted))
{
return OperationResultModel.Error("Error:", "Есть студенты, относящиеся к этой группе", ResultServiceStatusCode.ExsistItem);
}
return OperationResultModel.Success(null);
}
@ -43,7 +47,7 @@ namespace DepartmentDatabaseImplementation.Implementations
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> IncludingWhenReading(IQueryable<StudentGroup> query) => query.Include(x => x.AcademicPlan).Include(x => x.AcademicPlan.EducationDirection).Include(x => x.Lecturer);
protected override IQueryable<StudentGroup> OrderingWhenReading(IQueryable<StudentGroup> query) => query.OrderBy(x => x.EnrollmentYear).ThenBy(x => x.GroupNumber);
}

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>
/// Реализация IStudentService
/// </summary>
public class StudentService :
AbstractGenerticEntityService<StudentGetBindingModel, StudentSetBindingModel, Student, StudentListViewModel, StudentViewModel>,
IStudentService
{
protected override OperationResultModel AdditionalCheckingWhenAdding(DbContext context, StudentSetBindingModel model) => OperationResultModel.Success(null);
protected override OperationResultModel AdditionalCheckingWhenDeleting(DbContext context, Student entity, StudentGetBindingModel model) => OperationResultModel.Success(null);
protected override IQueryable<Student> AdditionalCheckingWhenReadingList(IQueryable<Student> query, StudentGetBindingModel model)
{
if (model.UserId.HasValue)
{
query = query.Where(x => x.UserId == model.UserId.Value);
}
if (model.StudentGroupId.HasValue)
{
query = query.Where(x => x.StudentGroupId == model.StudentGroupId.Value);
}
if (model.StudentState.HasValue)
{
query = query.Where(x => x.StudentState == (int)model.StudentState.Value);
}
return query;
}
protected override OperationResultModel AdditionalCheckingWhenUpdateing(DbContext context, StudentSetBindingModel model) => OperationResultModel.Success(null);
protected override void AdditionalDeleting(DbContext context, Student entity, StudentGetBindingModel model) { }
protected override Student GetUniqueEntity(StudentSetBindingModel model, DbContext context) => context.Set<Student>().FirstOrDefault(x => x.NumberOfBook == model.NumberOfBook && x.Id != model.Id);
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.EnrollmentYear).ThenBy(x => x.StudentGroup.GroupNumber).ThenBy(x => x.LastName).ThenBy(x => x.FirstName);
}
}

View File

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

View File

@ -16,6 +16,9 @@ using System.Collections.Generic;
namespace DepartmentWindowsDesktop.EntityControls
{
/// <summary>
/// Реализация контрола для преподавателя
/// </summary>
public partial class ControlLecturerElement :
GenericControlEntityElement<LecturerGetBindingModel, LecturerSetBindingModel, LecturerListViewModel, LecturerViewModel, LecturerBusinessLogic>,
IGenericControlEntityElement

View File

@ -11,6 +11,9 @@ using System.Collections.Generic;
namespace DepartmentWindowsDesktop.EntityControls
{
/// <summary>
/// Реализация контрола для списка преподавателей
/// </summary>
public partial class ControlLecturerList :
GenericControlEntityList<LecturerGetBindingModel, LecturerSetBindingModel, LecturerListViewModel, LecturerViewModel, LecturerBusinessLogic>,
IGenericControlEntityList

View File

@ -0,0 +1,33 @@

namespace DepartmentWindowsDesktop.EntityControls
{
partial class ControlStudentElement
{
/// <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,121 @@
using DepartmentBusinessLogic.BindingModels;
using DepartmentBusinessLogic.BusinessLogics;
using DepartmentBusinessLogic.ViewModels;
using DesktopTools.BaseControls;
using DesktopTools.Controls;
using DesktopTools.Helpers;
using DesktopTools.Interfaces;
using DesktopTools.Models;
using ModuleTools.BusinessLogics;
using ModuleTools.Extensions;
using SecurityBusinessLogic.BindingModels;
using SecurityBusinessLogic.BusinessLogics;
using SecurityBusinessLogic.ViewModels;
using System;
using System.Collections.Generic;
namespace DepartmentWindowsDesktop.EntityControls
{
/// <summary>
/// Реализация контрола для студента
/// </summary>
public partial class ControlStudentElement :
GenericControlEntityElement<StudentGetBindingModel, StudentSetBindingModel, StudentListViewModel, StudentViewModel, StudentBusinessLogic>,
IGenericControlEntityElement
{
public ControlStudentElement()
{
InitializeComponent();
Title = "Студент";
ControlId = new Guid("cbddf92c-8c00-4ad2-93e8-33c0d998a899");
_genericControlViewEntityElement = this;
}
public IControl GetInstanceGenericControl() => new ControlStudentElement() { ControlId = Guid.NewGuid() };
public ControlViewEntityElementConfiguration GetConfigControl() => new()
{
ControlOnMoveElem = new Dictionary<string, (string Title, EventHandler Event)>
{
{ "ToolStripMenuItemAddUser", ("Добавить пользователя", (object sender, EventArgs e) => { AddUser(); }) },
{ "ToolStripMenuItemPasswordReset", ("Сброс пароля пользователя", (object sender, EventArgs e) => { PasswordReset(); }) }
}
};
/// <summary>
/// Поиск пользователя под учетку, либо добавление нового, если не найдено
/// </summary>
private void AddUser()
{
var model = new StudentSetBindingModel();
if (FillModel(model))
{
var logic = DependencyManager.Instance.Resolve<UserBusinessLogic>();
var userName = $"{model.LastName}{(model.FirstName.IsNotEmpty() ? $" {model.FirstName[0]}." : string.Empty)}{(model.Patronymic.IsNotEmpty() ? $"{model.Patronymic[0]}." : string.Empty)}";
var result = logic.GetList(new UserGetBindingModel { UserNameForSearch = userName });
if (result != null)
{
if (result.List.Count > 1)
{
DialogHelper.MessageException("Существует несколько пользователей с такой сигнатурой", "Ошибка");
return;
}
if (result.List.Count == 1)
{
model.UserId = result.List[0].Id;
}
else
{
var newuser = logic.Create(new UserSetBindingModel
{
Login = userName,
Password = model.NumberOfBook,
Avatar = model.Photo
});
if (newuser == null)
{
DialogHelper.MessageException(logic.Errors, "Ошибка при создании пользователя");
return;
}
model.UserId = newuser.Id;
}
var controls = tabPageMain.Controls.Find($"ControlUserId", true);
if (controls != null)
{
(controls[0] as AbstractBaseControl).SetValue(model);
}
}
}
}
/// <summary>
/// Сброс пароля пользователя
/// </summary>
private void PasswordReset()
{
if (_element == null)
{
return;
}
var model = new StudentSetBindingModel();
if (FillModel(model))
{
var logic = DependencyManager.Instance.Resolve<UserBusinessLogic>();
var user = logic.GetElement(new UserGetBindingModel { Id = _element.UserId });
if (user == null)
{
DialogHelper.MessageException(logic.Errors, "Ошибка при получении пользователя");
return;
}
user.Password = model.NumberOfBook;
user = logic.Update(Mapper.MapToClass<UserViewModel, UserSetBindingModel>(user, true));
if (user == null)
{
DialogHelper.MessageException(logic.Errors, "Ошибка при получении пользователя");
return;
}
DialogHelper.MessageInformation("Пароль сброшен", "Успех");
}
}
}
}

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 ControlStudentList
{
/// <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,51 @@
using DepartmentBusinessLogic.BindingModels;
using DepartmentBusinessLogic.BusinessLogics;
using DepartmentBusinessLogic.Enums;
using DepartmentBusinessLogic.ViewModels;
using DesktopTools.Controls;
using DesktopTools.Enums;
using DesktopTools.Interfaces;
using DesktopTools.Models;
using ModuleTools.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
namespace DepartmentWindowsDesktop.EntityControls
{
/// <summary>
/// Реализация контрола для списка студентов
/// </summary>
public partial class ControlStudentList :
GenericControlEntityList<StudentGetBindingModel, StudentSetBindingModel, StudentListViewModel, StudentViewModel, StudentBusinessLogic>,
IGenericControlEntityList
{
public ControlStudentList()
{
InitializeComponent();
Title = "Студенты";
ControlId = new Guid("5fef6c48-efb8-4d52-a02e-27beb914f397");
AccessOperation = AccessOperation.Студенты;
ControlViewEntityElement = new ControlStudentElement();
_genericControlViewEntityList = this;
}
public IControl GetInstanceGenericControl() => new ControlStudentList() { ControlId = Guid.NewGuid() };
public ControlViewEntityListConfiguration GetConfigControl() => new()
{
PaginationOn = true,
PageNamesForPagination = Enum.GetValues(typeof(StudentState)).OfType<StudentState>().ToList().Select(x =>
new PageNamesForPaginationModel
{
Key = x,
Value = x.ToString()
})?.ToList(),
ParentPropertyName = "StudentState",
HideToolStripButton = new List<ToolStripButtonListNames>
{
ToolStripButtonListNames.toolStripButtonAdd
}
};
}
}

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

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