оставила только один приказ - буду менять его типы. так, по мелочи - подгружаются пока что ВСЕ направления, группы и т.д., открывается форма создания/редактирования направления. перехожу к созданию системы учета текущего декана

This commit is contained in:
2025-06-19 01:26:17 +04:00
parent 86eb94436f
commit c37dbbf68c
60 changed files with 777 additions and 1941 deletions

View File

@@ -30,46 +30,26 @@
{
MainPages = new TabControl();
StudentsPage = new TabPage();
progressBarStudents = new ProgressBar();
dataGridViewStudents = new DataGridView();
menuStrip1 = new MenuStrip();
фильтрацияToolStripMenuItem = new ToolStripMenuItem();
SpecPage = new TabPage();
progressBarSpecs = new ProgressBar();
dataGridViewSpecs = new DataGridView();
menuStrip2 = new MenuStrip();
toolStripMenuItem1 = new ToolStripMenuItem();
добавитьНаправлениеToolStripMenuItem = new ToolStripMenuItem();
GroupsPage = new TabPage();
progressBarGroups = new ProgressBar();
dataGridViewGroups = new DataGridView();
menuStrip3 = new MenuStrip();
toolStripMenuItem2 = new ToolStripMenuItem();
добавитьГруппуToolStripMenuItem = new ToolStripMenuItem();
OrdersPage = new TabPage();
tabControl1 = new TabControl();
tabPageAddStudent = new TabPage();
dataGridViewAddOrders = new DataGridView();
menuStrip4 = new MenuStrip();
создатьПриказToolStripMenuItem = new ToolStripMenuItem();
создатьПриказToolStripMenuItem1 = new ToolStripMenuItem();
tabPageExpulsion = new TabPage();
dataGridView3 = new DataGridView();
menuStrip5 = new MenuStrip();
toolStripMenuItem3 = new ToolStripMenuItem();
toolStripMenuItem4 = new ToolStripMenuItem();
tabPageAcademicLeave = new TabPage();
dataGridView4 = new DataGridView();
menuStrip6 = new MenuStrip();
toolStripMenuItem5 = new ToolStripMenuItem();
toolStripMenuItem6 = new ToolStripMenuItem();
tabPageNextCourse = new TabPage();
dataGridView5 = new DataGridView();
menuStrip7 = new MenuStrip();
toolStripMenuItem7 = new ToolStripMenuItem();
toolStripMenuItem8 = new ToolStripMenuItem();
tabPageOtherSpec = new TabPage();
dataGridView6 = new DataGridView();
menuStrip8 = new MenuStrip();
toolStripMenuItem9 = new ToolStripMenuItem();
toolStripMenuItem10 = new ToolStripMenuItem();
MainPages.SuspendLayout();
StudentsPage.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewStudents).BeginInit();
@@ -81,22 +61,7 @@
((System.ComponentModel.ISupportInitialize)dataGridViewGroups).BeginInit();
menuStrip3.SuspendLayout();
OrdersPage.SuspendLayout();
tabControl1.SuspendLayout();
tabPageAddStudent.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewAddOrders).BeginInit();
menuStrip4.SuspendLayout();
tabPageExpulsion.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView3).BeginInit();
menuStrip5.SuspendLayout();
tabPageAcademicLeave.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView4).BeginInit();
menuStrip6.SuspendLayout();
tabPageNextCourse.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView5).BeginInit();
menuStrip7.SuspendLayout();
tabPageOtherSpec.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView6).BeginInit();
menuStrip8.SuspendLayout();
SuspendLayout();
//
// MainPages
@@ -117,6 +82,7 @@
//
// StudentsPage
//
StudentsPage.Controls.Add(progressBarStudents);
StudentsPage.Controls.Add(dataGridViewStudents);
StudentsPage.Controls.Add(menuStrip1);
StudentsPage.Location = new Point(4, 29);
@@ -128,6 +94,13 @@
StudentsPage.Text = "Студенты";
StudentsPage.UseVisualStyleBackColor = true;
//
// progressBarStudents
//
progressBarStudents.Location = new Point(475, 345);
progressBarStudents.Name = "progressBarStudents";
progressBarStudents.Size = new Size(125, 29);
progressBarStudents.TabIndex = 5;
//
// dataGridViewStudents
//
dataGridViewStudents.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
@@ -162,6 +135,7 @@
//
// SpecPage
//
SpecPage.Controls.Add(progressBarSpecs);
SpecPage.Controls.Add(dataGridViewSpecs);
SpecPage.Controls.Add(menuStrip2);
SpecPage.Location = new Point(4, 29);
@@ -173,8 +147,17 @@
SpecPage.Text = "Направления";
SpecPage.UseVisualStyleBackColor = true;
//
// progressBarSpecs
//
progressBarSpecs.Location = new Point(475, 345);
progressBarSpecs.Name = "progressBarSpecs";
progressBarSpecs.Size = new Size(125, 29);
progressBarSpecs.TabIndex = 5;
//
// dataGridViewSpecs
//
dataGridViewSpecs.AllowUserToAddRows = false;
dataGridViewSpecs.AllowUserToDeleteRows = false;
dataGridViewSpecs.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewSpecs.BackgroundColor = Color.AliceBlue;
dataGridViewSpecs.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
@@ -188,6 +171,7 @@
dataGridViewSpecs.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewSpecs.Size = new Size(1068, 682);
dataGridViewSpecs.TabIndex = 2;
dataGridViewSpecs.CellDoubleClick += dataGridViewSpecs_CellDoubleClick;
//
// menuStrip2
//
@@ -210,9 +194,11 @@
добавитьНаправлениеToolStripMenuItem.Name = обавитьНаправлениеToolStripMenuItem";
добавитьНаправлениеToolStripMenuItem.Size = new Size(187, 24);
добавитьНаправлениеToolStripMenuItem.Text = "Добавить направление";
добавитьНаправлениеToolStripMenuItem.Click += добавитьНаправлениеToolStripMenuItem_Click;
//
// GroupsPage
//
GroupsPage.Controls.Add(progressBarGroups);
GroupsPage.Controls.Add(dataGridViewGroups);
GroupsPage.Controls.Add(menuStrip3);
GroupsPage.Location = new Point(4, 29);
@@ -223,6 +209,13 @@
GroupsPage.Text = "Группы";
GroupsPage.UseVisualStyleBackColor = true;
//
// progressBarGroups
//
progressBarGroups.Location = new Point(475, 345);
progressBarGroups.Name = "progressBarGroups";
progressBarGroups.Size = new Size(125, 29);
progressBarGroups.TabIndex = 4;
//
// dataGridViewGroups
//
dataGridViewGroups.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
@@ -263,64 +256,23 @@
//
// OrdersPage
//
OrdersPage.Controls.Add(tabControl1);
OrdersPage.BackColor = Color.LightSteelBlue;
OrdersPage.Controls.Add(menuStrip4);
OrdersPage.Location = new Point(4, 29);
OrdersPage.Margin = new Padding(3, 4, 3, 4);
OrdersPage.Name = "OrdersPage";
OrdersPage.Size = new Size(1074, 718);
OrdersPage.TabIndex = 3;
OrdersPage.Text = "Приказы";
OrdersPage.UseVisualStyleBackColor = true;
//
// tabControl1
//
tabControl1.Controls.Add(tabPageAddStudent);
tabControl1.Controls.Add(tabPageExpulsion);
tabControl1.Controls.Add(tabPageAcademicLeave);
tabControl1.Controls.Add(tabPageNextCourse);
tabControl1.Controls.Add(tabPageOtherSpec);
tabControl1.Dock = DockStyle.Fill;
tabControl1.Location = new Point(0, 0);
tabControl1.Margin = new Padding(3, 4, 3, 4);
tabControl1.Name = "tabControl1";
tabControl1.SelectedIndex = 0;
tabControl1.Size = new Size(1074, 718);
tabControl1.TabIndex = 0;
//
// tabPageAddStudent
//
tabPageAddStudent.Controls.Add(dataGridViewAddOrders);
tabPageAddStudent.Controls.Add(menuStrip4);
tabPageAddStudent.Location = new Point(4, 29);
tabPageAddStudent.Margin = new Padding(3, 4, 3, 4);
tabPageAddStudent.Name = "tabPageAddStudent";
tabPageAddStudent.Padding = new Padding(3, 4, 3, 4);
tabPageAddStudent.Size = new Size(1066, 685);
tabPageAddStudent.TabIndex = 0;
tabPageAddStudent.Text = "Зачисление";
tabPageAddStudent.UseVisualStyleBackColor = true;
//
// dataGridViewAddOrders
//
dataGridViewAddOrders.BackgroundColor = Color.LightSteelBlue;
dataGridViewAddOrders.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewAddOrders.Dock = DockStyle.Fill;
dataGridViewAddOrders.Location = new Point(3, 32);
dataGridViewAddOrders.Margin = new Padding(3, 4, 3, 4);
dataGridViewAddOrders.Name = "dataGridViewAddOrders";
dataGridViewAddOrders.RowHeadersWidth = 51;
dataGridViewAddOrders.RowTemplate.Height = 24;
dataGridViewAddOrders.Size = new Size(1060, 649);
dataGridViewAddOrders.TabIndex = 0;
//
// menuStrip4
//
menuStrip4.ImageScalingSize = new Size(20, 20);
menuStrip4.Items.AddRange(new ToolStripItem[] { создатьПриказToolStripMenuItem, создатьПриказToolStripMenuItem1 });
menuStrip4.Location = new Point(3, 4);
menuStrip4.Location = new Point(0, 0);
menuStrip4.Name = "menuStrip4";
menuStrip4.Size = new Size(1060, 28);
menuStrip4.TabIndex = 1;
menuStrip4.Size = new Size(1074, 28);
menuStrip4.TabIndex = 2;
menuStrip4.Text = "menuStrip4";
//
// создатьПриказToolStripMenuItem
@@ -335,195 +287,6 @@
создатьПриказToolStripMenuItem1.Size = new Size(131, 24);
создатьПриказToolStripMenuItem1.Text = "Создать приказ";
//
// tabPageExpulsion
//
tabPageExpulsion.Controls.Add(dataGridView3);
tabPageExpulsion.Controls.Add(menuStrip5);
tabPageExpulsion.Location = new Point(4, 29);
tabPageExpulsion.Margin = new Padding(3, 4, 3, 4);
tabPageExpulsion.Name = "tabPageExpulsion";
tabPageExpulsion.Padding = new Padding(3, 4, 3, 4);
tabPageExpulsion.Size = new Size(1066, 685);
tabPageExpulsion.TabIndex = 1;
tabPageExpulsion.Text = "Отчисление";
tabPageExpulsion.UseVisualStyleBackColor = true;
//
// dataGridView3
//
dataGridView3.BackgroundColor = Color.LightSteelBlue;
dataGridView3.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView3.Dock = DockStyle.Fill;
dataGridView3.Location = new Point(3, 32);
dataGridView3.Margin = new Padding(3, 4, 3, 4);
dataGridView3.Name = "dataGridView3";
dataGridView3.RowHeadersWidth = 51;
dataGridView3.RowTemplate.Height = 24;
dataGridView3.Size = new Size(1060, 649);
dataGridView3.TabIndex = 2;
//
// menuStrip5
//
menuStrip5.ImageScalingSize = new Size(20, 20);
menuStrip5.Items.AddRange(new ToolStripItem[] { toolStripMenuItem3, toolStripMenuItem4 });
menuStrip5.Location = new Point(3, 4);
menuStrip5.Name = "menuStrip5";
menuStrip5.Size = new Size(1060, 28);
menuStrip5.TabIndex = 3;
menuStrip5.Text = "menuStrip5";
//
// toolStripMenuItem3
//
toolStripMenuItem3.Name = "toolStripMenuItem3";
toolStripMenuItem3.Size = new Size(108, 24);
toolStripMenuItem3.Text = "Фильтрация";
//
// toolStripMenuItem4
//
toolStripMenuItem4.Name = "toolStripMenuItem4";
toolStripMenuItem4.Size = new Size(131, 24);
toolStripMenuItem4.Text = "Создать приказ";
//
// tabPageAcademicLeave
//
tabPageAcademicLeave.Controls.Add(dataGridView4);
tabPageAcademicLeave.Controls.Add(menuStrip6);
tabPageAcademicLeave.Location = new Point(4, 29);
tabPageAcademicLeave.Margin = new Padding(3, 4, 3, 4);
tabPageAcademicLeave.Name = "tabPageAcademicLeave";
tabPageAcademicLeave.Size = new Size(1066, 685);
tabPageAcademicLeave.TabIndex = 2;
tabPageAcademicLeave.Text = "Академический отпуск";
tabPageAcademicLeave.UseVisualStyleBackColor = true;
//
// dataGridView4
//
dataGridView4.BackgroundColor = Color.LightSteelBlue;
dataGridView4.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView4.Dock = DockStyle.Fill;
dataGridView4.Location = new Point(0, 28);
dataGridView4.Margin = new Padding(3, 4, 3, 4);
dataGridView4.Name = "dataGridView4";
dataGridView4.RowHeadersWidth = 51;
dataGridView4.RowTemplate.Height = 24;
dataGridView4.Size = new Size(1066, 657);
dataGridView4.TabIndex = 2;
//
// menuStrip6
//
menuStrip6.ImageScalingSize = new Size(20, 20);
menuStrip6.Items.AddRange(new ToolStripItem[] { toolStripMenuItem5, toolStripMenuItem6 });
menuStrip6.Location = new Point(0, 0);
menuStrip6.Name = "menuStrip6";
menuStrip6.Size = new Size(1066, 28);
menuStrip6.TabIndex = 3;
menuStrip6.Text = "menuStrip6";
//
// toolStripMenuItem5
//
toolStripMenuItem5.Name = "toolStripMenuItem5";
toolStripMenuItem5.Size = new Size(108, 24);
toolStripMenuItem5.Text = "Фильтрация";
//
// toolStripMenuItem6
//
toolStripMenuItem6.Name = "toolStripMenuItem6";
toolStripMenuItem6.Size = new Size(131, 24);
toolStripMenuItem6.Text = "Создать приказ";
//
// tabPageNextCourse
//
tabPageNextCourse.Controls.Add(dataGridView5);
tabPageNextCourse.Controls.Add(menuStrip7);
tabPageNextCourse.Location = new Point(4, 29);
tabPageNextCourse.Margin = new Padding(3, 4, 3, 4);
tabPageNextCourse.Name = "tabPageNextCourse";
tabPageNextCourse.Size = new Size(1066, 685);
tabPageNextCourse.TabIndex = 3;
tabPageNextCourse.Text = "Перевод на следующий курс";
tabPageNextCourse.UseVisualStyleBackColor = true;
//
// dataGridView5
//
dataGridView5.BackgroundColor = Color.LightSteelBlue;
dataGridView5.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView5.Dock = DockStyle.Fill;
dataGridView5.Location = new Point(0, 28);
dataGridView5.Margin = new Padding(3, 4, 3, 4);
dataGridView5.Name = "dataGridView5";
dataGridView5.RowHeadersWidth = 51;
dataGridView5.RowTemplate.Height = 24;
dataGridView5.Size = new Size(1066, 657);
dataGridView5.TabIndex = 2;
//
// menuStrip7
//
menuStrip7.ImageScalingSize = new Size(20, 20);
menuStrip7.Items.AddRange(new ToolStripItem[] { toolStripMenuItem7, toolStripMenuItem8 });
menuStrip7.Location = new Point(0, 0);
menuStrip7.Name = "menuStrip7";
menuStrip7.Size = new Size(1066, 28);
menuStrip7.TabIndex = 3;
menuStrip7.Text = "menuStrip7";
//
// toolStripMenuItem7
//
toolStripMenuItem7.Name = "toolStripMenuItem7";
toolStripMenuItem7.Size = new Size(108, 24);
toolStripMenuItem7.Text = "Фильтрация";
//
// toolStripMenuItem8
//
toolStripMenuItem8.Name = "toolStripMenuItem8";
toolStripMenuItem8.Size = new Size(131, 24);
toolStripMenuItem8.Text = "Создать приказ";
//
// tabPageOtherSpec
//
tabPageOtherSpec.Controls.Add(dataGridView6);
tabPageOtherSpec.Controls.Add(menuStrip8);
tabPageOtherSpec.Location = new Point(4, 29);
tabPageOtherSpec.Margin = new Padding(3, 4, 3, 4);
tabPageOtherSpec.Name = "tabPageOtherSpec";
tabPageOtherSpec.Size = new Size(1066, 685);
tabPageOtherSpec.TabIndex = 4;
tabPageOtherSpec.Text = "Перевод на другое направление";
tabPageOtherSpec.UseVisualStyleBackColor = true;
//
// dataGridView6
//
dataGridView6.BackgroundColor = Color.LightSteelBlue;
dataGridView6.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView6.Dock = DockStyle.Fill;
dataGridView6.Location = new Point(0, 28);
dataGridView6.Margin = new Padding(3, 4, 3, 4);
dataGridView6.Name = "dataGridView6";
dataGridView6.RowHeadersWidth = 51;
dataGridView6.RowTemplate.Height = 24;
dataGridView6.Size = new Size(1066, 657);
dataGridView6.TabIndex = 2;
//
// menuStrip8
//
menuStrip8.ImageScalingSize = new Size(20, 20);
menuStrip8.Items.AddRange(new ToolStripItem[] { toolStripMenuItem9, toolStripMenuItem10 });
menuStrip8.Location = new Point(0, 0);
menuStrip8.Name = "menuStrip8";
menuStrip8.Size = new Size(1066, 28);
menuStrip8.TabIndex = 3;
menuStrip8.Text = "menuStrip8";
//
// toolStripMenuItem9
//
toolStripMenuItem9.Name = "toolStripMenuItem9";
toolStripMenuItem9.Size = new Size(108, 24);
toolStripMenuItem9.Text = "Фильтрация";
//
// toolStripMenuItem10
//
toolStripMenuItem10.Name = "toolStripMenuItem10";
toolStripMenuItem10.Size = new Size(131, 24);
toolStripMenuItem10.Text = "Создать приказ";
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
@@ -531,7 +294,6 @@
AutoSize = true;
ClientSize = new Size(1082, 751);
Controls.Add(MainPages);
MainMenuStrip = menuStrip4;
Margin = new Padding(3, 4, 3, 4);
Name = "FormMain";
Text = "Главная";
@@ -552,32 +314,9 @@
menuStrip3.ResumeLayout(false);
menuStrip3.PerformLayout();
OrdersPage.ResumeLayout(false);
tabControl1.ResumeLayout(false);
tabPageAddStudent.ResumeLayout(false);
tabPageAddStudent.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewAddOrders).EndInit();
OrdersPage.PerformLayout();
menuStrip4.ResumeLayout(false);
menuStrip4.PerformLayout();
tabPageExpulsion.ResumeLayout(false);
tabPageExpulsion.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView3).EndInit();
menuStrip5.ResumeLayout(false);
menuStrip5.PerformLayout();
tabPageAcademicLeave.ResumeLayout(false);
tabPageAcademicLeave.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView4).EndInit();
menuStrip6.ResumeLayout(false);
menuStrip6.PerformLayout();
tabPageNextCourse.ResumeLayout(false);
tabPageNextCourse.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView5).EndInit();
menuStrip7.ResumeLayout(false);
menuStrip7.PerformLayout();
tabPageOtherSpec.ResumeLayout(false);
tabPageOtherSpec.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView6).EndInit();
menuStrip8.ResumeLayout(false);
menuStrip8.PerformLayout();
ResumeLayout(false);
}
@@ -599,31 +338,11 @@
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem добавитьНаправлениеToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem добавитьГруппуToolStripMenuItem;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPageAddStudent;
private System.Windows.Forms.TabPage tabPageExpulsion;
private System.Windows.Forms.TabPage tabPageAcademicLeave;
private System.Windows.Forms.TabPage tabPageNextCourse;
private System.Windows.Forms.TabPage tabPageOtherSpec;
private System.Windows.Forms.DataGridView dataGridViewAddOrders;
private System.Windows.Forms.MenuStrip menuStrip4;
private System.Windows.Forms.ToolStripMenuItem создатьПриказToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem создатьПриказToolStripMenuItem1;
private System.Windows.Forms.DataGridView dataGridView3;
private System.Windows.Forms.MenuStrip menuStrip5;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem3;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem4;
private System.Windows.Forms.DataGridView dataGridView5;
private System.Windows.Forms.MenuStrip menuStrip7;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem7;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem8;
private System.Windows.Forms.DataGridView dataGridView6;
private System.Windows.Forms.MenuStrip menuStrip8;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem9;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem10;
private DataGridView dataGridView4;
private MenuStrip menuStrip6;
private ToolStripMenuItem toolStripMenuItem5;
private ToolStripMenuItem toolStripMenuItem6;
private ProgressBar progressBarGroups;
private MenuStrip menuStrip4;
private ToolStripMenuItem создатьПриказToolStripMenuItem;
private ToolStripMenuItem создатьПриказToolStripMenuItem1;
private ProgressBar progressBarStudents;
private ProgressBar progressBarSpecs;
}
}

View File

@@ -11,48 +11,34 @@ namespace App_contingent_university.Forms
private readonly StudentLogic _studentLogic;
private readonly GroupLogic _groupLogic;
private readonly SpecializationLogic _specializationLogic;
private readonly AddStudentOrderLogic _addStudentOrderLogic;
private readonly ExpulsionOrderLogic _expulsionOrderLogic;
private readonly AcademicLeaveOrderLogic _cademicLeaveOrderLogic;
private readonly ChangeSpecializationOrderLogic _changeSpecializationOrderLogic;
private readonly NextCourseOrderLogic _nextCourseOrderLogic;
private readonly OrderLogic _orderLogic;
private readonly StudentRepository studentRepository;
private readonly GroupRepository groupRepository;
private readonly SpecializationRepository specializationRepository;
private readonly AddStudentsOrderRepository addStudentsOrderRepository;
private readonly ExpulsionOrderRepository expulsionOrderRepository;
private readonly AcademicLeaveOrderRepository academicLeaveOrderRepository;
private readonly ChangeSpecializationOrderRepository changeSpecializationOrderRepository;
private readonly NextCourseOrderRepository nextCourseOrderRepository;
private readonly OrderRepository orderRepository;
public FormMain(StudentLogic studentLogic, GroupLogic groupLogic, SpecializationLogic specializationLogic,
AddStudentOrderLogic addStudentOrderLogic, ExpulsionOrderLogic expulsionOrderLogic,
AcademicLeaveOrderLogic cademicLeaveOrderLogic, ChangeSpecializationOrderLogic changeSpecializationOrderLogic,
NextCourseOrderLogic nextCourseOrderLogic,
private int? _id;
public int Id
{
set { _id = value; }
}
public FormMain(StudentLogic studentLogic, GroupLogic groupLogic, SpecializationLogic specializationLogic,
OrderLogic orderLogic,
StudentRepository studentRepository, GroupRepository groupRepository, SpecializationRepository specializationRepository,
AddStudentsOrderRepository addStudentsOrderRepository, ExpulsionOrderRepository expulsionOrderRepository,
AcademicLeaveOrderRepository academicLeaveOrderRepository, ChangeSpecializationOrderRepository changeSpecializationOrderRepository,
NextCourseOrderRepository nextCourseOrderRepository
OrderRepository orderRepository
)
{
_studentLogic = studentLogic;
_groupLogic = groupLogic;
_specializationLogic = specializationLogic;
_addStudentOrderLogic = addStudentOrderLogic;
_expulsionOrderLogic = expulsionOrderLogic;
_cademicLeaveOrderLogic = cademicLeaveOrderLogic;
_changeSpecializationOrderLogic = changeSpecializationOrderLogic;
_nextCourseOrderLogic = nextCourseOrderLogic;
_orderLogic = orderLogic;
this.studentRepository = studentRepository;
this.groupRepository = groupRepository;
this.specializationRepository = specializationRepository;
this.addStudentsOrderRepository = addStudentsOrderRepository;
this.expulsionOrderRepository = expulsionOrderRepository;
this.academicLeaveOrderRepository = academicLeaveOrderRepository;
this.changeSpecializationOrderRepository = changeSpecializationOrderRepository;
this.nextCourseOrderRepository = nextCourseOrderRepository;
this.orderRepository = orderRepository;
InitializeComponent();
@@ -63,51 +49,129 @@ namespace App_contingent_university.Forms
// InitializeComponent();
//}
private bool _studentsLoaded = false;
private bool _groupsLoaded = false;
private bool _specsLoaded = false;
private async void MainPages_SelectedIndexChanged(object sender, EventArgs e)
{
if (MainPages.SelectedTab == StudentsPage)
if (MainPages.SelectedTab == StudentsPage && !_studentsLoaded)
{
await LoadStudentsData();
_studentsLoaded = true;
}
else if (MainPages.SelectedTab == GroupsPage)
else if (MainPages.SelectedTab == GroupsPage && !_groupsLoaded)
{
await LoadGroupsData();
_groupsLoaded = true;
}
else if (MainPages.SelectedTab == SpecPage)
else if (MainPages.SelectedTab == SpecPage && !_specsLoaded)
{
await LoadSpecializationData();
_specsLoaded = true;
}
else if (MainPages.SelectedTab == tabPageAddStudent)
else if (MainPages.SelectedTab == OrdersPage)
{
// Дополнительная логика для этой вкладки
}
}
private async Task ShowLoading(bool show, ProgressBar progressBar)
{
if (progressBar.InvokeRequired)
{
progressBar.Invoke(new Action(() => ShowLoading(show, progressBar)));
return;
}
progressBar.Visible = show;
progressBar.Style = show ? ProgressBarStyle.Marquee : ProgressBarStyle.Blocks;
if (show) progressBar.BringToFront();
}
private async Task LoadStudentsData()
{
var studLogic = new StudentLogic(studentRepository, groupRepository, specializationRepository);
var students = await studLogic.GetViewModel();
await ShowLoading(true, progressBarStudents);
try
{
var studLogic = new StudentLogic(studentRepository, groupRepository, specializationRepository);
var students = await studLogic.GetViewModel();
dataGridViewStudents.DataSource = students;
dataGridViewStudents.AutoGenerateColumns = true;
dataGridViewStudents.DataSource = students;
dataGridViewStudents.AutoGenerateColumns = true;
}
finally
{
await ShowLoading(false, progressBarStudents);
}
}
private async Task LoadGroupsData()
{
var groupLogic = new GroupLogic(specializationRepository, groupRepository);
var groups = await groupLogic.GetViewModel();
await ShowLoading(true, progressBarGroups);
try
{
var groupLogic = new GroupLogic(specializationRepository, groupRepository);
var groups = await groupLogic.GetViewModel();
dataGridViewGroups.DataSource = groups;
dataGridViewGroups.AutoGenerateColumns = true;
dataGridViewGroups.DataSource = groups;
dataGridViewGroups.AutoGenerateColumns = true;
}
finally
{
await ShowLoading(false, progressBarGroups);
}
}
private async Task LoadSpecializationData()
{
var specLogic = new SpecializationLogic(specializationRepository);
var specs = await specLogic.GetViewModel();
await ShowLoading(true, progressBarSpecs);
try
{
var specLogic = new SpecializationLogic(specializationRepository);
var specs = await specLogic.GetViewModel();
dataGridViewSpecs.DataSource = specs;
dataGridViewSpecs.AutoGenerateColumns = true;
dataGridViewSpecs.DataSource = specs;
dataGridViewSpecs.AutoGenerateColumns = true;
}
finally
{
await ShowLoading(false, progressBarSpecs);
}
}
private void добавитьНаправлениеToolStripMenuItem_Click(object sender, EventArgs e)
{
if (dataGridViewSpecs.SelectedRows.Count > 0)
{
var service = Program.ServiceProvider?.GetService(typeof(FormAddUpdSpec));
if (service is FormAddUpdSpec form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadSpecializationData();
}
}
}
}
private void dataGridViewSpecs_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0)
{
var selectedRow = dataGridViewSpecs.Rows[e.RowIndex];
var specId = (int)selectedRow.Cells["Id"].Value;
var service = Program.ServiceProvider?.GetService(typeof(FormAddUpdSpec));
if (service is FormAddUpdSpec form)
{
form.Id = specId;
if (form.ShowDialog() == DialogResult.OK)
{
LoadSpecializationData();
}
}
}
}
}
}

View File

@@ -120,49 +120,16 @@
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="menuStrip2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>153, 17</value>
</metadata>
<metadata name="menuStrip2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>153, 17</value>
</metadata>
<metadata name="menuStrip3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>289, 17</value>
</metadata>
<metadata name="menuStrip3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>289, 17</value>
</metadata>
<metadata name="menuStrip4.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>425, 17</value>
</metadata>
<metadata name="menuStrip4.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>425, 17</value>
</metadata>
<metadata name="menuStrip5.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>561, 17</value>
</metadata>
<metadata name="menuStrip5.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>561, 17</value>
</metadata>
<metadata name="menuStrip6.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>697, 17</value>
</metadata>
<metadata name="menuStrip6.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>697, 17</value>
</metadata>
<metadata name="menuStrip7.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>833, 17</value>
</metadata>
<metadata name="menuStrip7.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>833, 17</value>
</metadata>
<metadata name="menuStrip8.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>969, 17</value>
</metadata>
<metadata name="menuStrip8.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>969, 17</value>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>25</value>
</metadata>
</root>

View File

@@ -28,73 +28,78 @@
/// </summary>
private void InitializeComponent()
{
this.textBoxCode = new System.Windows.Forms.TextBox();
this.labelCode = new System.Windows.Forms.Label();
this.textBoxName = new System.Windows.Forms.TextBox();
this.labelName = new System.Windows.Forms.Label();
this.buttonOK = new System.Windows.Forms.Button();
this.SuspendLayout();
textBoxCode = new TextBox();
labelCode = new Label();
textBoxName = new TextBox();
labelName = new Label();
buttonOK = new Button();
SuspendLayout();
//
// textBoxCode
//
this.textBoxCode.Location = new System.Drawing.Point(109, 48);
this.textBoxCode.Name = "textBoxCode";
this.textBoxCode.Size = new System.Drawing.Size(160, 22);
this.textBoxCode.TabIndex = 13;
textBoxCode.Location = new Point(109, 60);
textBoxCode.Margin = new Padding(3, 4, 3, 4);
textBoxCode.Name = "textBoxCode";
textBoxCode.Size = new Size(160, 27);
textBoxCode.TabIndex = 13;
//
// labelCode
//
this.labelCode.AutoSize = true;
this.labelCode.Location = new System.Drawing.Point(14, 54);
this.labelCode.Name = "labelCode";
this.labelCode.Size = new System.Drawing.Size(31, 16);
this.labelCode.TabIndex = 12;
this.labelCode.Text = "Код";
labelCode.AutoSize = true;
labelCode.Location = new Point(14, 68);
labelCode.Name = "labelCode";
labelCode.Size = new Size(35, 20);
labelCode.TabIndex = 12;
labelCode.Text = "Код";
//
// textBoxName
//
this.textBoxName.Location = new System.Drawing.Point(109, 12);
this.textBoxName.Name = "textBoxName";
this.textBoxName.Size = new System.Drawing.Size(160, 22);
this.textBoxName.TabIndex = 11;
textBoxName.Location = new Point(109, 15);
textBoxName.Margin = new Padding(3, 4, 3, 4);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(160, 27);
textBoxName.TabIndex = 11;
//
// labelName
//
this.labelName.AutoSize = true;
this.labelName.Location = new System.Drawing.Point(14, 18);
this.labelName.Name = "labelName";
this.labelName.Size = new System.Drawing.Size(73, 16);
this.labelName.TabIndex = 10;
this.labelName.Text = "Название";
labelName.AutoSize = true;
labelName.Location = new Point(14, 22);
labelName.Name = "labelName";
labelName.Size = new Size(77, 20);
labelName.TabIndex = 10;
labelName.Text = "Название";
//
// buttonOK
//
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonOK.BackColor = System.Drawing.Color.Orange;
this.buttonOK.ForeColor = System.Drawing.Color.Black;
this.buttonOK.Location = new System.Drawing.Point(163, 134);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(113, 37);
this.buttonOK.TabIndex = 9;
this.buttonOK.Text = "Сохранить";
this.buttonOK.UseVisualStyleBackColor = false;
buttonOK.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonOK.BackColor = Color.Orange;
buttonOK.ForeColor = Color.Black;
buttonOK.Location = new Point(163, 168);
buttonOK.Margin = new Padding(3, 4, 3, 4);
buttonOK.Name = "buttonOK";
buttonOK.Size = new Size(113, 46);
buttonOK.TabIndex = 9;
buttonOK.Text = "Сохранить";
buttonOK.UseVisualStyleBackColor = false;
buttonOK.Click += buttonOK_Click;
//
// FormAddUpdSpec
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.LightSteelBlue;
this.ClientSize = new System.Drawing.Size(288, 183);
this.Controls.Add(this.textBoxCode);
this.Controls.Add(this.labelCode);
this.Controls.Add(this.textBoxName);
this.Controls.Add(this.labelName);
this.Controls.Add(this.buttonOK);
this.Name = "FormAddUpdSpec";
this.Text = "Создать/редактировать";
this.ResumeLayout(false);
this.PerformLayout();
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.LightSteelBlue;
ClientSize = new Size(288, 229);
Controls.Add(textBoxCode);
Controls.Add(labelCode);
Controls.Add(textBoxName);
Controls.Add(labelName);
Controls.Add(buttonOK);
Margin = new Padding(3, 4, 3, 4);
Name = "FormAddUpdSpec";
Text = "Создать/редактировать";
Load += FormAddUpdSpec_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion

View File

@@ -1,20 +1,92 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Controller.BusinessLogic;
using Controller.Repository;
using DataModels.Models;
namespace App_contingent_university.Forms
{
public partial class FormAddUpdSpec : Form
{
public FormAddUpdSpec()
private readonly SpecializationRepository specializationRepository;
private readonly SpecializationLogic specializationLogic;
private int? _id;
public int Id
{
set
{
_id = value;
}
}
public FormAddUpdSpec(SpecializationLogic logic, SpecializationRepository repo)
{
specializationLogic = logic;
specializationRepository = repo;
InitializeComponent();
}
private async Task LoadData()
{
if (!_id.HasValue) return;
try
{
// Добавляем индикатор загрузки
textBoxCode.Text = "Загрузка...";
textBoxName.Text = "Загрузка...";
// Явно ожидаем загрузку
var spec = await specializationRepository.Get(_id.Value);
if (spec != null)
{
textBoxCode.Text = spec.Code ?? "Не указано";
textBoxName.Text = spec.Name ?? "Не указано";
if (spec.FacultyId == 0) // Проверка на недопустимое значение
{
MessageBox.Show("Ошибка: не указан факультет");
return;
}
}
else
{
MessageBox.Show("Специализация не найдена");
}
}
catch (Exception ex)
{
MessageBox.Show($"Ошибка загрузки: {ex.Message}");
textBoxCode.Text = "Ошибка";
textBoxName.Text = "Ошибка";
}
}
private async void buttonOK_Click(object sender, EventArgs e)
{
try
{
var spec = new Specialization
{
Id = _id ?? 0,
Code = textBoxCode.Text,
Name = textBoxName.Text,
};
if (_id.HasValue)
{
await specializationRepository.Update(spec);
}
else await specializationRepository.Add(spec);
}
catch (Exception ex)
{
throw;
}
}
private void FormAddUpdSpec_Load(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

@@ -1,17 +1,17 @@
<?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
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>
@@ -26,36 +26,36 @@
<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
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
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
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
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
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
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
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->

View File

@@ -10,53 +10,51 @@ namespace App_contingent_university
{
internal static class Program
{
public static IServiceProvider? ServiceProvider { get; private set; }
[STAThread]
static void Main()
{
var services = ConfigureServices();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Создаем скоуп и запускаем приложение
using (var scope = services.CreateScope())
{
var form = scope.ServiceProvider.GetRequiredService<FormMain>();
Application.Run(form);
}
// Настройка сервисов
var services = ConfigureServices();
ServiceProvider = services.BuildServiceProvider();
// Создание главной формы через DI
using var scope = ServiceProvider.CreateScope();
var mainForm = scope.ServiceProvider.GetRequiredService<FormMain>();
Application.Run(mainForm);
}
static ServiceProvider ConfigureServices()
static ServiceCollection ConfigureServices()
{
var services = new ServiceCollection();
// 👉 Настройка ApiService
services.AddHttpClient(); // 👈 обязательно!
services.AddHttpClient();
// 👉 Репозитории
// Регистрация репозиториев (Singleton, так как они должны жить всё время работы приложения)
services.AddSingleton<StudentRepository>();
services.AddSingleton<GroupRepository>();
services.AddSingleton<SpecializationRepository>();
services.AddSingleton<AddStudentsOrderRepository>();
services.AddSingleton<ExpulsionOrderRepository>();
services.AddSingleton<AcademicLeaveOrderRepository>();
services.AddSingleton<ChangeSpecializationOrderRepository>();
services.AddSingleton<NextCourseOrderRepository>();
services.AddSingleton<OrderRepository>();
// 👉 Логика
// Регистрация бизнес-логики (Singleton)
services.AddSingleton<StudentLogic>();
services.AddSingleton<GroupLogic>();
services.AddSingleton<SpecializationLogic>();
services.AddSingleton<AddStudentOrderLogic>();
services.AddSingleton<ExpulsionOrderLogic>();
services.AddSingleton<AcademicLeaveOrderLogic>();
services.AddSingleton<ChangeSpecializationOrderLogic>();
services.AddSingleton<NextCourseOrderLogic>();
services.AddSingleton<OrderLogic>();
// 👉 Главная форма (все зависимости будут автоматически внедрены в конструктор)
// Регистрация форм:
// Главная форма - Singleton
services.AddSingleton<FormMain>();
return services.BuildServiceProvider();
// Остальные формы - Transient (создаются новые инстансы при каждом запросе)
services.AddTransient<FormAddUpdSpec>();
// Добавьте другие формы по аналогии
return services;
}
}
}

View File

@@ -1,9 +0,0 @@
using DataModels.Orders;
namespace Controller.BusinessLogic
{
public class AcademicLeaveOrderLogic
{
}
}

View File

@@ -1,9 +0,0 @@
using DataModels.Orders;
namespace Controller.BusinessLogic
{
public class AddStudentOrderLogic
{
}
}

View File

@@ -1,9 +0,0 @@
using DataModels.Orders;
namespace Controller.BusinessLogic
{
public class ChangeSpecializationOrderLogic
{
}
}

View File

@@ -1,9 +0,0 @@
using DataModels.Orders;
namespace Controller.BusinessLogic
{
public class ExpulsionOrderLogic
{
}
}

View File

@@ -1,8 +0,0 @@
using DataModels.Orders;
namespace Controller.BusinessLogic
{
public class NextCourseOrderLogic
{
}
}

View File

@@ -0,0 +1,8 @@

namespace Controller.BusinessLogic
{
public class OrderLogic
{
}
}

View File

@@ -15,14 +15,14 @@ namespace Controller.BusinessLogic
public async Task<List<SpecialisationViewModel>> GetViewModel()
{
//var specs = await _specializationRepository.GetAll();
var specs = await _specializationRepository.GetAll();
var specs = new List<Specialization>
{
new Specialization{Id = 1, Code = "1234", Name = "Программная инженерия"},
new Specialization{Id = 2, Code = "5678", Name = "Информатика"},
//var specs = new List<Specialization>
//{
// new Specialization{Id = 1, Code = "1234", Name = "Программная инженерия"},
// new Specialization{Id = 2, Code = "5678", Name = "Информатика"},
};
//};
var results = new List<SpecialisationViewModel>();

View File

@@ -20,50 +20,50 @@ namespace Controller.BusinessLogic
public async Task<List<StudentViewModel>> GetViewModel()
{
//var students = await _studentRepository.GetAll();
var students = await _studentRepository.GetAll();
var students = new List<Student>
{
new Student { Id = 1, Name = "Иванов", GroupId = 1, SpecializationId = null, Status = Status.Обучается },
new Student { Id = 2, Name = "Петров", GroupId = null, SpecializationId = null, Status = Status.Академ },
new Student { Id = 3, Name = "Сидорова", GroupId = 2, SpecializationId = null }
};
//var students = new List<Student>
//{
// new Student { Id = 1, Name = "Иванов", GroupId = 1, SpecializationId = null, Status = Status.AcademicLeave },
// new Student { Id = 2, Name = "Петров", GroupId = null, SpecializationId = null, Status = Status.Studying },
// new Student { Id = 3, Name = "Сидорова", GroupId = 2, SpecializationId = null }
//};
var result = new List<StudentViewModel>();
var groups = new List<Group>
{
new Group { Id = 1, Name = "Группа 101", Course = 1, SpecializationId = 1, MaxStudentCount = 25, Number = 101 },
new Group { Id = 2, Name = "Группа 202", Course = 2, SpecializationId = 2, MaxStudentCount = 30, Number = 202 },
new Group { Id = 3, Name = "Группа 303", Course = 3, SpecializationId = 3, MaxStudentCount = 20, Number = 303 }
};
//var groups = new List<Group>
// {
// new Group { Id = 1, Name = "Группа 101", Course = 1, SpecializationId = 1, MaxStudentCount = 25, Number = 101 },
// new Group { Id = 2, Name = "Группа 202", Course = 2, SpecializationId = 2, MaxStudentCount = 30, Number = 202 },
// new Group { Id = 3, Name = "Группа 303", Course = 3, SpecializationId = 3, MaxStudentCount = 20, Number = 303 }
// };
// Моковые данные специализаций
var specializations = new List<Specialization>
{
new Specialization { Id = 1, Name = "Информатика", Code = "INF" },
new Specialization { Id = 2, Name = "Математика", Code = "MATH" },
new Specialization { Id = 3, Name = "Физика", Code = "PHYS" }
};
//var specializations = new List<Specialization>
// {
// new Specialization { Id = 1, Name = "Информатика", Code = "INF" },
// new Specialization { Id = 2, Name = "Математика", Code = "MATH" },
// new Specialization { Id = 3, Name = "Физика", Code = "PHYS" }
// };
foreach (var student in students)
{
//var group = student.GroupId.HasValue
// ? await _groupRepository.Get(student.GroupId.Value) : null;
//var specialization = student.SpecializationId.HasValue
// ? await _specializationRepository.Get(student.SpecializationId.Value) : null;
var group = student.GroupId.HasValue
? groups.FirstOrDefault(g => g.Id == student.GroupId.Value)
: null;
? await _groupRepository.Get(student.GroupId.Value) : null;
var specialization = student.SpecializationId.HasValue
? specializations.FirstOrDefault(s => s.Id == student.SpecializationId.Value)
: group?.SpecializationId != null
? specializations.FirstOrDefault(s => s.Id == group.SpecializationId)
: null;
? await _specializationRepository.Get(student.SpecializationId.Value) : null;
//var group = student.GroupId.HasValue
// ? groups.FirstOrDefault(g => g.Id == student.GroupId.Value)
// : null;
//var specialization = student.SpecializationId.HasValue
// ? specializations.FirstOrDefault(s => s.Id == student.SpecializationId.Value)
// : group?.SpecializationId != null
// ? specializations.FirstOrDefault(s => s.Id == group.SpecializationId)
// : null;
result.Add(new StudentViewModel(student, group, specialization));
}

View File

@@ -1,43 +0,0 @@
using Controller.Contracts;
using DataModels.Orders;
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;
namespace Controller.Repository
{
public class AcademicLeaveOrderRepository : AbstractRepository<AcademicLeaveOrder, OrderSearch>
{
HttpClient _httpClient;
public override string BaseUrl { get; set; } = "https://university/api/academOrders";
public AcademicLeaveOrderRepository(HttpClient httpClient) : base(httpClient)
{
_httpClient = httpClient;
}
public override async Task<AcademicLeaveOrder> Update(AcademicLeaveOrder entity)
{
var response = await _httpClient.PutAsJsonAsync($"{BaseUrl}/{entity.Id}", entity);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<AcademicLeaveOrder>()
?? throw new JsonException("Ошибка при десериализации факультета");
}
public override string BuildQueryString(OrderSearch search)
{
var query = HttpUtility.ParseQueryString(string.Empty);
if (search.OrderType.HasValue)
query["orderType"] = search.OrderType.ToString();
if (search.Number.HasValue)
query["number"] = search.Number.ToString();
if (search.Date.HasValue)
query["date"] = search.Date.ToString();
return query.ToString() ?? string.Empty;
}
}
}

View File

@@ -1,43 +0,0 @@
using Controller.Contracts;
using DataModels.Orders;
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;
namespace Controller.Repository
{
public class ChangeSpecializationOrderRepository : AbstractRepository<ChangeSpecializationOrder, OrderSearch>
{
HttpClient _httpClient;
public override string BaseUrl { get; set; } = "https://university/api/changeSpecOrders";
public ChangeSpecializationOrderRepository(HttpClient httpClient) : base(httpClient)
{
_httpClient = httpClient;
}
public override async Task<ChangeSpecializationOrder> Update(ChangeSpecializationOrder entity)
{
var response = await _httpClient.PutAsJsonAsync($"{BaseUrl}/{entity.Id}", entity);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ChangeSpecializationOrder>()
?? throw new JsonException("Ошибка при десериализации факультета");
}
public override string BuildQueryString(OrderSearch search)
{
var query = HttpUtility.ParseQueryString(string.Empty);
if (search.OrderType.HasValue)
query["orderType"] = search.OrderType.ToString();
if (search.Number.HasValue)
query["number"] = search.Number.ToString();
if (search.Date.HasValue)
query["date"] = search.Date.ToString();
return query.ToString() ?? string.Empty;
}
}
}

View File

@@ -1,43 +0,0 @@
using Controller.Contracts;
using DataModels.Orders;
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;
namespace Controller.Repository
{
public class ExpulsionOrderRepository : AbstractRepository<ExpulsionOrder, OrderSearch>
{
HttpClient _httpClient;
public override string BaseUrl { get; set; } = "http://localhost:8000/expulsion-orders";
public ExpulsionOrderRepository(HttpClient httpClient) : base(httpClient)
{
_httpClient = httpClient;
}
public override async Task<ExpulsionOrder> Update(ExpulsionOrder entity)
{
var response = await _httpClient.PutAsJsonAsync($"{BaseUrl}/{entity.Id}", entity);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ExpulsionOrder>()
?? throw new JsonException("Ошибка при десериализации факультета");
}
public override string BuildQueryString(OrderSearch search)
{
var query = HttpUtility.ParseQueryString(string.Empty);
if (search.OrderType.HasValue)
query["orderType"] = search.OrderType.ToString();
if (search.Number.HasValue)
query["number"] = search.Number.ToString();
if (search.Date.HasValue)
query["date"] = search.Date.ToString();
return query.ToString() ?? string.Empty;
}
}
}

View File

@@ -1,43 +0,0 @@
using Controller.Contracts;
using DataModels.Orders;
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;
namespace Controller.Repository
{
public class NextCourseOrderRepository : AbstractRepository<NextCourseOrder, OrderSearch>
{
HttpClient _httpClient;
public override string BaseUrl { get; set; } = "http://localhost:8000/next-course-orders";
public NextCourseOrderRepository(HttpClient httpClient) : base(httpClient)
{
_httpClient = httpClient;
}
public override async Task<NextCourseOrder> Update(NextCourseOrder entity)
{
var response = await _httpClient.PutAsJsonAsync($"{BaseUrl}/{entity.Id}", entity);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<NextCourseOrder>()
?? throw new JsonException("Ошибка при десериализации факультета");
}
public override string BuildQueryString(OrderSearch search)
{
var query = HttpUtility.ParseQueryString(string.Empty);
if (search.OrderType.HasValue)
query["orderType"] = search.OrderType.ToString();
if (search.Number.HasValue)
query["number"] = search.Number.ToString();
if (search.Date.HasValue)
query["date"] = search.Date.ToString();
return query.ToString() ?? string.Empty;
}
}
}

View File

@@ -1,26 +1,26 @@
using Controller.Contracts;
using DataModels.Orders;
using DataModels.Models;
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;
namespace Controller.Repository
{
public class AddStudentsOrderRepository : AbstractRepository<AddStudentsOrder, OrderSearch>
public class OrderRepository : AbstractRepository<Order, OrderSearch>
{
HttpClient _httpClient;
public override string BaseUrl { get; set; } = "https://university/api/addOrders";
public AddStudentsOrderRepository(HttpClient httpClient) : base(httpClient)
public OrderRepository(HttpClient httpClient) : base(httpClient)
{
_httpClient = httpClient;
}
public override async Task<AddStudentsOrder> Update(AddStudentsOrder entity)
public override async Task<Order> Update(Order entity)
{
var response = await _httpClient.PutAsJsonAsync($"{BaseUrl}/{entity.Id}", entity);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<AddStudentsOrder>()
return await response.Content.ReadFromJsonAsync<Order>()
?? throw new JsonException("Ошибка при десериализации факультета");
}

View File

@@ -42,8 +42,8 @@ namespace Controller.ViewModels
[DisplayName("Специализация")]
public string? Specialization { get; set; }
//[Browsable(false)]
[DisplayName("id spec")]
[Browsable(false)]
//[DisplayName("id spec")]
public int? SpecializationId { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using DataModels.Models;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Xml.Linq;
namespace Controller.ViewModels
{
public class OrdersView
{
public OrdersView(Order order, Specialization spec)
{
}
}
}

View File

@@ -12,7 +12,7 @@ namespace Controller.ViewModels
Code = spec.Code ?? "Не указано";
}
[Browsable(false)]
//[Browsable(false)]
public int Id { get; set; }
[DisplayName("Наименование")]

View File

@@ -30,7 +30,10 @@ namespace DataModels.Models
public string? FullName()
{
return $"{Name}-{Course}{Number}";
string result = string.Empty;
if (Course < 5) result = $"{Name}бд-{Course}{Number}";
else result = $"{Name}-{Course}{Number}";
return result;
}
public bool HavePlace()

View File

@@ -5,45 +5,69 @@ using Xceed.Words.NET;
namespace DataModels.Models
{
public abstract class AbstractOrder : Model
public class Order : Model
{
[JsonPropertyName("students")]
[JsonIgnore] // Чтобы избежать циклических ссылок
public virtual List<Student> Students { get; set; } = new List<Student>();
public List<Student> Students { get; set; } = new List<Student>();
[JsonPropertyName("order_type")]
public OrderType? OrderType { get; set; }
[JsonPropertyName("reason")]
public Reason? Reason { get; set; }
[JsonPropertyName("number")]
public int? Number { get; set; }
[JsonPropertyName("current_dean_id")]
[ForeignKey("Dean")]
public int? CurrentDeanId { get; set; }
[JsonPropertyName("date")]
public DateTime? Date { get; set; } = DateTime.Now;
[JsonPropertyName("document")]
[Column(TypeName = "bytea")]
public byte[]? Document { get; set; }
// Навигационное свойство
[JsonPropertyName("date_start")]
public DateTime? DateStart { get; set; }
[JsonPropertyName("date_end")]
public DateTime? DateEnd { get; set; }
[JsonPropertyName("new_spec_id")]
[ForeignKey("Specialization")]
public int? NewSpecId { get; set; }
[JsonPropertyName("next_course")]
public int? NextCourse { get; set; }
[JsonIgnore]
public virtual Dean? Dean { get; set; }
public Specialization? NewSpecialization { get; set; }
[JsonIgnore]
public Dean? Dean { get; set; }
// Абстрактные методы для работы с документами
[JsonIgnore]
public abstract string TemplatePath { get; }
public string? TemplatePath { get; }
public abstract void FillTemplate(DocX doc);
public void CreateDocument(string path)
public void FillTemplate(DocX doc, OrderType type)
{
}
public void CreateDocument(string path, OrderType type)
{
var doc = DocX.Load(TemplatePath);
FillTemplate(doc);
FillTemplate(doc, type);
doc.SaveAs(path);
}
}

View File

@@ -6,10 +6,10 @@ namespace DataModels.Models
public class Specialization : Model
{
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
public string? Name { get; set; } = string.Empty;
[JsonPropertyName("code")]
public string Code { get; set; } = string.Empty;
public string? Code { get; set; } = string.Empty;
[JsonPropertyName("faculty_id")]
[ForeignKey("Faculty")]

View File

@@ -9,7 +9,7 @@ namespace DataModels.Models
public string? LastName { get; set; } = string.Empty;
[JsonPropertyName("first_name")]
public string? FirstName { get; set; } = string.Empty;
public string? Name { get; set; } = string.Empty;
[JsonPropertyName("patronymic")]
public string? Patronymic { get; set; } = string.Empty;

View File

@@ -1,34 +0,0 @@
using DataModels.Enums;
using DataModels.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using Xceed.Words.NET;
namespace DataModels.Orders
{
public class AcademicLeaveOrder : AbstractOrder
{
[JsonPropertyName("date_start")]
public DateTime? DateStart { get; set; }
[JsonPropertyName("date_end")]
public DateTime? DateEnd { get; set; }
// Навигационные свойства
[JsonIgnore]
[ForeignKey("Dean")]
public override Dean? Dean { get; set; }
[JsonIgnore]
public override List<Student> Students { get; set; } = new List<Student>();
// Путь к шаблону документа
[JsonIgnore]
public override string TemplatePath => "Templates/AcademicLeaveTemplate.docx";
public override void FillTemplate(DocX doc)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,27 +0,0 @@
using DataModels.Enums;
using DataModels.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using Xceed.Words.NET;
namespace DataModels.Orders
{
public class AddStudentsOrder : AbstractOrder
{
[JsonIgnore]
[ForeignKey("Dean")]
public override Dean? Dean { get; set; }
[JsonPropertyName("students")]
public override List<Student> Students { get; set; } = new List<Student>();
// Путь к шаблону документа
[JsonIgnore]
public override string TemplatePath => "Templates/AddStudentsOrderTemplate.docx";
public override void FillTemplate(DocX doc)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,35 +0,0 @@
using DataModels.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using Xceed.Words.NET;
namespace DataModels.Orders
{
public class ChangeSpecializationOrder : AbstractOrder
{
[JsonPropertyName("new_spec_id")]
[ForeignKey("Specialization")]
public int? NewSpecId { get; set; }
// Навигационные свойства
[JsonIgnore]
public virtual Specialization? NewSpecialization { get; set; }
[JsonPropertyName("students")]
public override List<Student> Students { get; set; } = new List<Student>();
[JsonIgnore]
[ForeignKey("Dean")]
public override Dean? Dean { get; set; }
// Путь к шаблону документа
[JsonIgnore]
public override string TemplatePath => "Templates/ChangeSpecializationOrderTemplate.docx";
public override void FillTemplate(DocX doc)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,27 +0,0 @@
using DataModels.Enums;
using DataModels.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using Xceed.Words.NET;
namespace DataModels.Orders
{
public class ExpulsionOrder : AbstractOrder
{
[JsonIgnore]
[ForeignKey("Dean")]
public override Dean? Dean { get; set; }
[JsonPropertyName("students")]
public override List<Student> Students { get; set; } = new List<Student>();
// Путь к шаблону документа
[JsonIgnore]
public override string TemplatePath => "Templates/AddStudentsOrderTemplate.docx";
public override void FillTemplate(DocX doc)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,30 +0,0 @@
using DataModels.Enums;
using DataModels.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using Xceed.Words.NET;
namespace DataModels.Orders
{
public class NextCourseOrder : AbstractOrder
{
[JsonPropertyName("new_course")]
public int? NextCourse { get; set; }
[JsonIgnore]
[ForeignKey("Dean")]
public override Dean? Dean { get; set; }
[JsonPropertyName("students")]
public override List<Student> Students { get; set; } = new List<Student>();
// Путь к шаблону документа
[JsonIgnore]
public override string TemplatePath => "Templates/AddStudentsOrderTemplate.docx";
public override void FillTemplate(DocX doc)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,72 +0,0 @@
from sqlalchemy.orm import Session
from app.models.orders.academic_leave import AcademicLeaveOrder
from app.models.student import Student
from app.dtos.academic_leave_order_dto import AcademicLeaveOrderCreateDto, AcademicLeaveOrderUpdateDto
from app.dtos.academic_leave_order_dto import AcademicLeaveOrderSearchDto
from sqlalchemy import and_
def get_filtered_academic_leave_orders(db: Session, search: AcademicLeaveOrderSearchDto):
query = db.query(AcademicLeaveOrder)
if search.number is not None:
query = query.filter(AcademicLeaveOrder.number == search.number)
if search.reason is not None:
query = query.filter(AcademicLeaveOrder.reason == search.reason)
if search.current_dean_id is not None:
query = query.filter(AcademicLeaveOrder.current_dean_id == search.current_dean_id)
if search.date_start is not None:
query = query.filter(AcademicLeaveOrder.date_start >= search.date_start)
if search.date_end is not None:
query = query.filter(AcademicLeaveOrder.date_end <= search.date_end)
if search.student_id is not None:
query = query.join(AcademicLeaveOrder.students).filter(Student.id == search.student_id)
return query.all()
def get_academic_leave_order(db: Session, order_id: int):
return db.query(AcademicLeaveOrder).filter(AcademicLeaveOrder.id == order_id).first()
def get_all_academic_leave_orders(db: Session):
return db.query(AcademicLeaveOrder).all()
def create_academic_leave_order(db: Session, data: AcademicLeaveOrderCreateDto):
students = db.query(Student).filter(Student.id.in_(data.student_ids)).all()
db_order = AcademicLeaveOrder(
**data.model_dump(exclude={"student_ids"}),
students=students
)
db.add(db_order)
db.commit()
db.refresh(db_order)
return db_order
def update_academic_leave_order(db: Session, order_id: int, data: AcademicLeaveOrderUpdateDto):
db_order = db.get(AcademicLeaveOrder, order_id)
if not db_order:
return None
update_data = data.model_dump(exclude_unset=True, exclude={"student_ids"})
for key, value in update_data.items():
setattr(db_order, key, value)
if data.student_ids is not None:
db_order.students = db.query(Student).filter(Student.id.in_(data.student_ids)).all()
db.commit()
db.refresh(db_order)
return db_order
def delete_academic_leave_order(db: Session, order_id: int):
db_order = db.get(AcademicLeaveOrder, order_id)
if not db_order:
return None
db.delete(db_order)
db.commit()
return db_order

View File

@@ -0,0 +1,77 @@
from sqlalchemy.orm import Session
from app.models.order import Order
from app.models.student import Student
from app.dtos.order_dto import OrderSearchDto, OrderUpdateDto, OrderCreateDto, OrderDto, OrderType
def get_filtered_orders(db: Session, search: OrderSearchDto):
query = db.query(Order)
if search.order_type is not None:
query = query.filter(Order.order_type == search.order_type)
if search.reason is not None:
query = query.filter(Order.reason == search.reason)
if search.number is not None:
query = query.filter(Order.number == search.number)
if search.current_dean_id is not None:
query = query.filter(Order.current_dean_id == search.current_dean_id)
if search.date_start is not None:
query = query.filter(Order.date_start >= search.date_start)
if search.date_end is not None:
query = query.filter(Order.date_end <= search.date_end)
if search.new_spec_id is not None:
query = query.filter(Order.new_spec_id == search.new_spec_id)
if search.next_course is not None:
query = query.filter(Order.next_course == search.next_course)
if search.student_id is not None:
query = query.join(Order.students).filter(Student.id == search.student_id)
return query.all()
def get_order(db: Session, order_id: int):
return db.query(Order).filter(Order.id == order_id).first()
def get_all_orders(db: Session):
return db.query(Order).all()
def create_order(db: Session, data: OrderCreateDto):
students = db.query(Student).filter(Student.id.in_(data.student_ids)).all()
db_order = Order(
**data.model_dump(exclude={"student_ids"}),
students=students
)
db.add(db_order)
db.commit()
db.refresh(db_order)
return db_order
def update_order(db: Session, order_id: int, data: OrderUpdateDto):
db_order = db.get(Order, order_id)
if not db_order:
return None
update_data = data.model_dump(exclude_unset=True, exclude={"student_ids"})
for key, value in update_data.items():
setattr(db_order, key, value)
if data.student_ids is not None:
db_order.students = db.query(Student).filter(Student.id.in_(data.student_ids)).all()
db.commit()
db.refresh(db_order)
return db_order
def delete_order(db: Session, order_id: int):
db_order = db.get(Order, order_id)
if not db_order:
return None
db.delete(db_order)
db.commit()
return

View File

@@ -3,6 +3,4 @@ from .students_dto import StudentCreateDto, StudentDto, StudentFilterDto,Student
from .group_dto import GroupDto, GroupCreateDto, GroupSearchDto, GroupUpdateDto
from .faculty_dto import FacultyCreateDto, FacultyDto, FacultyUpdateDto
from .dean_dto import DeanCreateDto, DeanDto, DeanUpdateDto
from .add_students_dto import AddStudentsOrderCreateDto, AddStudentsOrderDto, AddStudentsOrderSearchDto, AddStudentsOrderUpdateDto
from .academic_leave_order_dto import AcademicLeaveOrderCreateDto, AcademicLeaveOrderDto, AcademicLeaveOrderSearchDto, AcademicLeaveOrderUpdateDto
from .change_specialization_order_dto import ChangeSpecializationOrderBaseDto, ChangeSpecializationOrderCreateDto, ChangeSpecializationOrderDto, ChangeSpecializationOrderSearchDto, ChangeSpecializationOrderUpdateDto
from .order_dto import OrderCreateDto, OrderDto, OrderSearchDto, OrderType, OrderUpdateDto

View File

@@ -1,35 +0,0 @@
from pydantic import BaseModel, ConfigDict
from typing import Optional, List
from datetime import datetime
from app.models.enums import OrderType, Reason
class AddStudentsOrderDto(BaseModel):
id: int
number: int
order_type: OrderType
reason: Reason
current_dean_id: int
date: datetime
model_config = ConfigDict(from_attributes=True)
class AddStudentsOrderCreateDto(BaseModel):
number: int
order_type: OrderType
reason: str
current_dean_id: int
date: Optional[datetime] = None
class AddStudentsOrderUpdateDto(BaseModel):
number: Optional[int] = None
order_type: Optional[OrderType] = None
reason: Optional[Reason] = None
current_dean_id: Optional[int] = None
date: Optional[datetime] = None
class AddStudentsOrderSearchDto(BaseModel):
number: Optional[int] = None
reason: Optional[Reason] = None
current_dean_id: Optional[int] = None
date: Optional[datetime] = None
student_id: Optional[int] = None

View File

@@ -1,33 +0,0 @@
from pydantic import BaseModel
from datetime import datetime
from typing import Optional, List
from app.dtos.students_dto import StudentDto
from app.models.enums import OrderType, Reason
class ChangeSpecializationOrderBaseDto(BaseModel):
number: Optional[int]
reason: Optional[Reason]
order_type: Optional[OrderType]
date: Optional[datetime]
current_dean_id: Optional[int]
new_spec_id: Optional[int]
class ChangeSpecializationOrderCreateDto(ChangeSpecializationOrderBaseDto):
student_ids: List[int]
class ChangeSpecializationOrderUpdateDto(ChangeSpecializationOrderBaseDto):
student_ids: List[int]
class ChangeSpecializationOrderDto(ChangeSpecializationOrderBaseDto):
id: int
students: List[StudentDto]
class Config:
orm_mode = True
class ChangeSpecializationOrderSearchDto(BaseModel):
number: Optional[int] = None
reason: Optional[Reason] = None
order_type: Optional[OrderType] = None
new_spec_id: Optional[int] = None
current_dean_id: Optional[int] = None

View File

@@ -1,19 +0,0 @@
# schemas/contingent_report.py
from pydantic import BaseModel
from typing import List, Optional
from datetime import datetime
class ContingentReportCreateDTO(BaseModel):
current_dean_id: Optional[int]
date: Optional[datetime] = None
specialization_ids: Optional[List[int]] = None
group_ids: Optional[List[int]] = None
class ContingentReportDTO(ContingentReportCreateDTO):
id: int
file_name: Optional[str]
file_type: Optional[str]
class Config:
orm_mode = True

View File

@@ -1,39 +0,0 @@
# dtos/expulsion_order_dto.py
from pydantic import BaseModel, ConfigDict
from typing import Optional, List
from datetime import datetime
from app.models.enums import Reason, OrderType
class ExpulsionOrderSearchDto(BaseModel):
number: Optional[int] = None
reason: Optional[Reason] = None
current_dean_id: Optional[int] = None
date: Optional[datetime] = None
student_id: Optional[int] = None
class ExpulsionOrderDto(BaseModel):
id: int
order_type: OrderType
reason: Reason
number: int
current_dean_id: int
date: datetime
student_ids: List[int]
model_config = ConfigDict(from_attributes=True)
class ExpulsionOrderCreateDto(BaseModel):
order_type: OrderType
reason: Reason
number: int
current_dean_id: int
date: Optional[datetime] = None
student_ids: List[int]
class ExpulsionOrderUpdateDto(BaseModel):
order_type: Optional[OrderType] = None
reason: Optional[Reason] = None
number: Optional[int] = None
current_dean_id: Optional[int] = None
date: Optional[datetime] = None
student_ids: Optional[List[int]] = None

View File

@@ -1,43 +0,0 @@
# dtos/next_course_order_dto.py
from pydantic import BaseModel, ConfigDict
from typing import Optional, List
from datetime import datetime
from app.models.enums import Reason, OrderType
class NextCourseOrderSearchDto(BaseModel):
number: Optional[int] = None
reason: Optional[Reason] = None
current_dean_id: Optional[int] = None
date: Optional[datetime] = None
student_id: Optional[int] = None
new_course: Optional[int] = None
class NextCourseOrderDto(BaseModel):
id: int
order_type: OrderType
reason: Reason
number: int
current_dean_id: int
date: datetime
new_course: Optional[int] = None
student_ids: List[int]
model_config = ConfigDict(from_attributes=True)
class NextCourseOrderCreateDto(BaseModel):
order_type: OrderType
reason: Reason
number: int
current_dean_id: int
date: Optional[datetime] = None
new_course: Optional[int] = None
student_ids: List[int]
class NextCourseOrderUpdateDto(BaseModel):
order_type: Optional[OrderType] = None
reason: Optional[Reason] = None
number: Optional[int] = None
current_dean_id: Optional[int] = None
date: Optional[datetime] = None
new_course: Optional[int] = None
student_ids: Optional[List[int]] = None

View File

@@ -1,48 +1,52 @@
from pydantic import BaseModel, ConfigDict
from datetime import datetime
from typing import Optional, List
from app.models.enums import OrderType, Reason
from app.models.enums import Reason, OrderType
from typing import Optional
from datetime import datetime
class AcademicLeaveOrderSearchDto(BaseModel):
number: Optional[int] = None
reason: Optional[Reason] = None
current_dean_id: Optional[int] = None
date_start: Optional[datetime] = None
date_end: Optional[datetime] = None
student_id: Optional[int] = None
class AcademicLeaveOrderDto(BaseModel):
id: int
order_type: OrderType
reason: Reason
number: int
current_dean_id: int
date: datetime
date_start: datetime
date_end: datetime
student_ids: List[int] # Список ID студентов
model_config = ConfigDict(from_attributes=True)
class AcademicLeaveOrderCreateDto(BaseModel):
order_type: OrderType
reason: Reason
number: int
current_dean_id: int
date_start: datetime
date_end: datetime
student_ids: List[int]
class AcademicLeaveOrderUpdateDto(BaseModel):
class OrderSearchDto(BaseModel):
order_type: Optional[OrderType] = None
reason: Optional[Reason] = None
number: Optional[int] = None
current_dean_id: Optional[int] = None
date_start: Optional[datetime] = None
date_end: Optional[datetime] = None
student_ids: Optional[List[int]] = None
student_id: Optional[int] = None
new_spec_id: Optional[int] = None
next_course: Optional[int] = None
class OrderDto(BaseModel):
id: int
order_type: OrderType
reason: Reason
number: int
current_dean_id: int
date: datetime
date_start: Optional[datetime] = None
date_end: Optional[datetime] = None
new_spec_id: Optional[int] = None
next_course: Optional[int] = None
student_ids: List[int]
model_config = ConfigDict(from_attributes=True)
class OrderCreateDto(BaseModel):
order_type: OrderType
reason: Reason
number: int
current_dean_id: int
date_start: Optional[datetime] = None
date_end: Optional[datetime] = None
new_spec_id: Optional[int] = None
next_course: Optional[int] = None
student_ids: List[int]
class OrderUpdateDto(BaseModel):
order_type: Optional[OrderType] = None
reason: Optional[Reason] = None
number: Optional[int] = None
current_dean_id: Optional[int] = None
date_start: Optional[datetime] = None
date_end: Optional[datetime] = None
new_spec_id: Optional[int] = None
next_course: Optional[int] = None
student_ids: Optional[List[int]] = None

View File

@@ -1,16 +1,10 @@
from .base import Model, Base
from .student import Student
from .group import Group
from .contingent_report import ContingentReport
from .orders.academic_leave import AcademicLeaveOrder
from .orders.add_students import AddStudentsOrder
from .orders.change_specialization import ChangeSpecializationOrder
from .orders.expulsion import ExpulsionOrder
from .orders.next_course import NextCourseOrder
from .association_tables import add_student_association, expulsion_student_association, academ_student_association, change_student_association, next_student_association
from .association_tables import order_student_association
from .dean import Dean
from .enums import Status, OrderType, Reason
from .faculty import Faculty
from .learning_plan import LearningPlan
from .order import AbstractOrder
from .order import Order
from .specialization import Specialization

View File

@@ -2,37 +2,9 @@
from sqlalchemy import Table, Column, Integer, ForeignKey
from app.database import Base
add_student_association = Table(
'add_student_association',
order_student_association = Table(
'order_student_association',
Base.metadata,
Column('order_id', Integer, ForeignKey('add_students_orders.id')),
Column('student_id', Integer, ForeignKey('students.id'))
)
academ_student_association = Table(
'academ_student_association',
Base.metadata,
Column('order_id', Integer, ForeignKey('academic_leave_orders.id')),
Column('student_id', Integer, ForeignKey('students.id'))
)
expulsion_student_association = Table(
'expulsion_student_association',
Base.metadata,
Column('order_id', Integer, ForeignKey('expulsion_orders.id')),
Column('student_id', Integer, ForeignKey('students.id'))
)
change_student_association = Table(
'change_student_association',
Base.metadata,
Column('order_id', Integer, ForeignKey('change_specialization_orders.id')),
Column('student_id', Integer, ForeignKey('students.id'))
)
next_student_association = Table(
'next_student_association',
Base.metadata,
Column('order_id', Integer, ForeignKey('next_course_orders.id')),
Column('order_id', Integer, ForeignKey('orders.id')),
Column('student_id', Integer, ForeignKey('students.id'))
)

View File

@@ -1,45 +0,0 @@
from sqlalchemy import Column, Integer, ForeignKey, LargeBinary, String, DateTime, Enum, Table
from sqlalchemy.orm import relationship, Mapped, mapped_column
from enum import Enum as PyEnum
from datetime import datetime
from .base import Model
class ContingentReportType(PyEnum):
SPECIALIZATION = "specialization"
GROUP = "group"
# Ассоциативные таблицы для связи many-to-many
contingent_report_specializations = Table(
"contingent_report_specializations",
Model.metadata,
Column("report_id", Integer, ForeignKey("contingent_reports.id"), primary_key=True),
Column("specialization_id", Integer, ForeignKey("specializations.id"), primary_key=True)
)
contingent_report_groups = Table(
"contingent_report_groups",
Model.metadata,
Column("report_id", Integer, ForeignKey("contingent_reports.id"), primary_key=True),
Column("group_id", Integer, ForeignKey("groups.id"), primary_key=True)
)
class ContingentReport(Model):
__tablename__ = "contingent_reports"
current_dean_id = Column(Integer, ForeignKey("deans.id"))
date = Column(DateTime, default=datetime.utcnow)
# Документ
document = Column(LargeBinary)
file_name = Column(String)
file_type = Column(String)
# Тип отчета
report_type = Column(Enum(ContingentReportType))
# Связи
dean = relationship("Dean")
specializations = relationship("Specialization", secondary=contingent_report_specializations)
groups = relationship("Group", secondary=contingent_report_groups)

View File

@@ -5,15 +5,23 @@ from .base import Model
from .enums import OrderType, Reason
from datetime import datetime
class AbstractOrder(Model):
__abstract__ = True
class Order(Model):
__tablename__ = "orders"
order_type = Column(Enum(OrderType))
reason = Column(Enum(Reason))
number = Column(Integer)
current_dean_id = Column(Integer, ForeignKey("deans.id"))
date = Column(DateTime, default=datetime.now)
document = Column(LargeBinary)
date_start = Column(DateTime, default=datetime.now)
date_end = Column(DateTime, default=datetime.now)
new_spec_id = Column(Integer, ForeignKey("specializations.id"))
next_course = Column(Integer)
# document = Column(LargeBinary)
# students = relationship("Student", secondary="order_student_association")
# dean = relationship("Dean")
students = relationship("Student", secondary="order_student_association")
dean = relationship("Dean")
new_specialization = relationship("Specialization")

View File

@@ -1,13 +0,0 @@
# models/orders/academic_leave.py
from sqlalchemy import Column, DateTime
from ..order import AbstractOrder
from sqlalchemy.orm import relationship
class AcademicLeaveOrder(AbstractOrder):
__tablename__ = "academic_leave_orders"
date_start = Column(DateTime)
date_end = Column(DateTime)
students = relationship("Student", secondary="academ_student_association")
dean = relationship("Dean")

View File

@@ -1,10 +0,0 @@
# models/orders/add_students.py
from ..order import AbstractOrder
from sqlalchemy.orm import relationship
class AddStudentsOrder(AbstractOrder):
__tablename__ = "add_students_orders"
students = relationship("Student", secondary="add_student_association")
dean = relationship("Dean")

View File

@@ -1,13 +0,0 @@
# models/orders/change_specialization.py
from sqlalchemy import Column, Integer, ForeignKey
from ..order import AbstractOrder
from sqlalchemy.orm import relationship
class ChangeSpecializationOrder(AbstractOrder):
__tablename__ = "change_specialization_orders"
new_spec_id = Column(Integer, ForeignKey("specializations.id"))
new_specialization = relationship("Specialization")
students = relationship("Student", secondary="change_student_association")
dean = relationship("Dean")

View File

@@ -1,10 +0,0 @@
# models/orders/expulsion.py
from ..order import AbstractOrder
from sqlalchemy.orm import relationship
class ExpulsionOrder(AbstractOrder):
__tablename__ = "expulsion_orders"
students = relationship("Student", secondary="expulsion_student_association")
dean = relationship("Dean")

View File

@@ -1,13 +0,0 @@
# models/orders/next_course.py
from sqlalchemy import Column, Integer
from ..order import AbstractOrder
from sqlalchemy.orm import relationship
class NextCourseOrder(AbstractOrder):
__tablename__ = "next_course_orders"
# Можно добавить поле для нового курса, если нужно
new_course = Column(Integer)
students = relationship("Student", secondary="next_student_association")
dean = relationship("Dean")

View File

@@ -3,14 +3,8 @@ from .student_router import student_router
from .faculty_router import faculty_router
from .dean_router import dean_router
from .group_router import group_router
from .add_students_router import router_add
from .academic_leave_order_router import router_academ
from .change_specialization_order_router import router_change
from .expulsion_order_router import router_expulsion
from .next_course_order_router import router_next_course
from .contingent_report_router import router_report
from .order_router import router
from .learning_plan_router import router_plan
all_routers = [specialization_router, student_router, faculty_router,
dean_router, group_router, router_academ, router_add, router_change,
router_expulsion, router_next_course, router_report, router_plan]
dean_router, group_router, router , router_plan]

View File

@@ -1,56 +0,0 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.dtos.academic_leave_order_dto import (
AcademicLeaveOrderDto,
AcademicLeaveOrderCreateDto,
AcademicLeaveOrderUpdateDto
)
from app.crud.academic_leave_order import (
get_academic_leave_order,
get_all_academic_leave_orders,
create_academic_leave_order,
update_academic_leave_order,
delete_academic_leave_order
)
from app.db import get_db
from app.dtos.academic_leave_order_dto import AcademicLeaveOrderSearchDto
from app.crud.academic_leave_order import get_filtered_academic_leave_orders
router_academ = APIRouter(prefix="/academic-leave-orders", tags=["AcademicLeaveOrders"])
@router_academ.get("/search", response_model=list[AcademicLeaveOrderDto])
def search_orders(
search: AcademicLeaveOrderSearchDto = Depends(), db: Session = Depends(get_db)
):
return get_filtered_academic_leave_orders(db, search)
@router_academ.get("", response_model=list[AcademicLeaveOrderDto])
def list_orders(db: Session = Depends(get_db)):
return get_all_academic_leave_orders(db)
@router_academ.get("/{order_id}", response_model=AcademicLeaveOrderDto)
def get_order(order_id: int, db: Session = Depends(get_db)):
order = get_academic_leave_order(db, order_id)
if not order:
raise HTTPException(404, detail="Order not found")
return order
@router_academ.post("", response_model=AcademicLeaveOrderDto)
def create_order(data: AcademicLeaveOrderCreateDto, db: Session = Depends(get_db)):
return create_academic_leave_order(db, data)
@router_academ.put("/{order_id}", response_model=AcademicLeaveOrderDto)
def update_order(order_id: int, data: AcademicLeaveOrderUpdateDto, db: Session = Depends(get_db)):
updated = update_academic_leave_order(db, order_id, data)
if not updated:
raise HTTPException(404, detail="Order not found")
return updated
@router_academ.delete("/{order_id}", response_model=AcademicLeaveOrderDto)
def delete_order(order_id: int, db: Session = Depends(get_db)):
deleted = delete_academic_leave_order(db, order_id)
if not deleted:
raise HTTPException(404, detail="Order not found")
return deleted

View File

@@ -1,52 +0,0 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.db import get_db
from app.crud.add_students import (
get_add_order,
get_all_add_orders,
create_add_order,
update_add_order,
delete_add_order,
get_filtered_add_orders,
)
from app.dtos.add_students_dto import (
AddStudentsOrderDto,
AddStudentsOrderCreateDto,
AddStudentsOrderUpdateDto,
AddStudentsOrderSearchDto
)
router_add = APIRouter(prefix="/add-students-orders", tags=["AddStudentsOrder"])
@router_add.get("", response_model=list[AddStudentsOrderDto])
def get_all(db: Session = Depends(get_db)):
return get_all_add_orders(db)
@router_add.get("/{id}", response_model=AddStudentsOrderDto)
def get_by_id(id: int, db: Session = Depends(get_db)):
order = get_add_order(db, id)
if not order:
raise HTTPException(status_code=404, detail="Order not found")
return order
@router_add.post("", response_model=AddStudentsOrderDto)
def create(data: AddStudentsOrderCreateDto, db: Session = Depends(get_db)):
return create_add_order(db, data)
@router_add.put("/{id}", response_model=AddStudentsOrderDto)
def update(id: int, data: AddStudentsOrderUpdateDto, db: Session = Depends(get_db)):
updated = update_add_order(db, id, data)
if not updated:
raise HTTPException(status_code=404, detail="Order not found")
return updated
@router_add.delete("/{id}", response_model=AddStudentsOrderDto)
def delete(id: int, db: Session = Depends(get_db)):
deleted = delete_add_order(db, id)
if not deleted:
raise HTTPException(status_code=404, detail="Order not found")
return deleted
@router_add.get("/search", response_model=list[AddStudentsOrderDto])
def search(search: AddStudentsOrderSearchDto = Depends(), db: Session = Depends(get_db)):
return get_filtered_add_orders(db, search)

View File

@@ -1,52 +0,0 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.dtos.change_specialization_order_dto import (
ChangeSpecializationOrderDto,
ChangeSpecializationOrderCreateDto,
ChangeSpecializationOrderUpdateDto,
ChangeSpecializationOrderSearchDto
)
from app.crud.change_specialization_order import (
get_change_order,
get_all_change_orders,
create_change_order,
update_change_order,
delete_change_order,
get_filtered_change_orders
)
from app.db import get_db
router_change = APIRouter(prefix="/change-specialization-orders", tags=["ChangeSpecializationOrders"])
@router_change.get("/search", response_model=list[ChangeSpecializationOrderDto])
def search_orders(search: ChangeSpecializationOrderSearchDto = Depends(), db: Session = Depends(get_db)):
return get_filtered_change_orders(db, search)
@router_change.get("", response_model=list[ChangeSpecializationOrderDto])
def list_orders(db: Session = Depends(get_db)):
return get_all_change_orders(db)
@router_change.get("/{order_id}", response_model=ChangeSpecializationOrderDto)
def get_order(order_id: int, db: Session = Depends(get_db)):
order = get_change_order(db, order_id)
if not order:
raise HTTPException(404, detail="Order not found")
return order
@router_change.post("", response_model=ChangeSpecializationOrderDto)
def create_order(data: ChangeSpecializationOrderCreateDto, db: Session = Depends(get_db)):
return create_change_order(db, data)
@router_change.put("/{order_id}", response_model=ChangeSpecializationOrderDto)
def update_order(order_id: int, data: ChangeSpecializationOrderUpdateDto, db: Session = Depends(get_db)):
updated = update_change_order(db, order_id, data)
if not updated:
raise HTTPException(404, detail="Order not found")
return updated
@router_change.delete("/{order_id}", response_model=ChangeSpecializationOrderDto)
def delete_order(order_id: int, db: Session = Depends(get_db)):
deleted = delete_change_order(db, order_id)
if not deleted:
raise HTTPException(404, detail="Order not found")
return deleted

View File

@@ -1,40 +0,0 @@
# routers/contingent_report_router.py
from fastapi import APIRouter, Depends, HTTPException, Response
from sqlalchemy.orm import Session
from app.dtos.contingent_report_dto import ContingentReportCreateDTO, ContingentReportDTO
from app.crud import contingent_report as crud
from app.db import get_db
router_report = APIRouter(prefix="/contingent-reports", tags=["Contingent Reports"])
@router_report.post("/", response_model=ContingentReportDTO)
def generate_report(data: ContingentReportCreateDTO, db: Session = Depends(get_db)):
# ТУТ ты вызываешь свою функцию генерации отчета и получаешь документ:
# report_bytes = generate_report_bytes(data.specialization_ids, data.group_ids)
# пока заменим это заглушкой:
report_bytes = b"FAKE_DOCUMENT_DATA"
file_name = "report.docx"
file_type = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
return crud.create_contingent_report(
db=db,
report_data=data,
document_bytes=report_bytes,
file_name=file_name,
file_type=file_type
)
@router_report.get("/{report_id}/download")
def download_report(report_id: int, db: Session = Depends(get_db)):
report = crud.get_report_by_id(db, report_id)
if not report:
raise HTTPException(status_code=404, detail="Report not found")
return Response(
content=report.document,
media_type=report.file_type,
headers={
"Content-Disposition": f"attachment; filename={report.file_name}"
}
)

View File

@@ -1,57 +0,0 @@
# routers/expulsion_order_router.py
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List
from app.dtos.expulsion_order_dto import (
ExpulsionOrderDto,
ExpulsionOrderCreateDto,
ExpulsionOrderUpdateDto,
ExpulsionOrderSearchDto,
)
from app.crud.expulsion_order import (
get_expulsion_order,
get_all_expulsion_orders,
create_expulsion_order,
update_expulsion_order,
delete_expulsion_order,
get_filtered_expulsion_orders,
)
from app.db import get_db
router_expulsion = APIRouter(prefix="/expulsion-orders", tags=["ExpulsionOrders"])
@router_expulsion.get("/search", response_model=List[ExpulsionOrderDto])
def search_orders(
search: ExpulsionOrderSearchDto = Depends(), db: Session = Depends(get_db)
):
return get_filtered_expulsion_orders(db, search)
@router_expulsion.get("", response_model=List[ExpulsionOrderDto])
def list_orders(db: Session = Depends(get_db)):
return get_all_expulsion_orders(db)
@router_expulsion.get("/{order_id}", response_model=ExpulsionOrderDto)
def get_order(order_id: int, db: Session = Depends(get_db)):
order = get_expulsion_order(db, order_id)
if not order:
raise HTTPException(404, detail="Order not found")
return order
@router_expulsion.post("", response_model=ExpulsionOrderDto)
def create_order(data: ExpulsionOrderCreateDto, db: Session = Depends(get_db)):
return create_expulsion_order(db, data)
@router_expulsion.put("/{order_id}", response_model=ExpulsionOrderDto)
def update_order(order_id: int, data: ExpulsionOrderUpdateDto, db: Session = Depends(get_db)):
updated = update_expulsion_order(db, order_id, data)
if not updated:
raise HTTPException(404, detail="Order not found")
return updated
@router_expulsion.delete("/{order_id}", response_model=ExpulsionOrderDto)
def delete_order(order_id: int, db: Session = Depends(get_db)):
deleted = delete_expulsion_order(db, order_id)
if not deleted:
raise HTTPException(404, detail="Order not found")
return deleted

View File

@@ -1,57 +0,0 @@
# routers/next_course_order_router.py
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List
from app.dtos.next_course_order_dto import (
NextCourseOrderDto,
NextCourseOrderCreateDto,
NextCourseOrderUpdateDto,
NextCourseOrderSearchDto,
)
from app.crud.next_course_order import (
get_next_course_order,
get_all_next_course_orders,
create_next_course_order,
update_next_course_order,
delete_next_course_order,
get_filtered_next_course_orders,
)
from app.db import get_db
router_next_course = APIRouter(prefix="/next-course-orders", tags=["NextCourseOrders"])
@router_next_course.get("/search", response_model=List[NextCourseOrderDto])
def search_orders(
search: NextCourseOrderSearchDto = Depends(), db: Session = Depends(get_db)
):
return get_filtered_next_course_orders(db, search)
@router_next_course.get("", response_model=List[NextCourseOrderDto])
def list_orders(db: Session = Depends(get_db)):
return get_all_next_course_orders(db)
@router_next_course.get("/{order_id}", response_model=NextCourseOrderDto)
def get_order(order_id: int, db: Session = Depends(get_db)):
order = get_next_course_order(db, order_id)
if not order:
raise HTTPException(404, detail="Order not found")
return order
@router_next_course.post("", response_model=NextCourseOrderDto)
def create_order(data: NextCourseOrderCreateDto, db: Session = Depends(get_db)):
return create_next_course_order(db, data)
@router_next_course.put("/{order_id}", response_model=NextCourseOrderDto)
def update_order(order_id: int, data: NextCourseOrderUpdateDto, db: Session = Depends(get_db)):
updated = update_next_course_order(db, order_id, data)
if not updated:
raise HTTPException(404, detail="Order not found")
return updated
@router_next_course.delete("/{order_id}", response_model=NextCourseOrderDto)
def delete_order(order_id: int, db: Session = Depends(get_db)):
deleted = delete_next_course_order(db, order_id)
if not deleted:
raise HTTPException(404, detail="Order not found")
return deleted

View File

@@ -0,0 +1,58 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.dtos.order_dto import (
OrderDto,
OrderCreateDto,
OrderUpdateDto,
OrderSearchDto
)
from app.crud.order import (
get_order,
get_all_orders,
create_order,
update_order,
delete_order,
get_filtered_orders
)
from app.db import get_db
router = APIRouter(prefix="/orders", tags=["Orders"])
@router.get("/search", response_model=list[OrderDto])
def search_orders(
search: OrderSearchDto = Depends(), db: Session = Depends(get_db)
):
return get_filtered_orders(db, search)
@router.get("", response_model=list[OrderDto])
def list_orders(db: Session = Depends(get_db)):
return get_all_orders(db)
@router.get("/{order_id}", response_model=OrderDto)
def read_order(order_id: int, db: Session = Depends(get_db)):
order = get_order(db, order_id)
if not order:
raise HTTPException(404, detail="Order not found")
return order
@router.post("", response_model=OrderDto)
def create_new_order(data: OrderCreateDto, db: Session = Depends(get_db)):
return create_order(db, data)
@router.put("/{order_id}", response_model=OrderDto)
def update_existing_order(
order_id: int,
data: OrderUpdateDto,
db: Session = Depends(get_db)
):
updated = update_order(db, order_id, data)
if not updated:
raise HTTPException(404, detail="Order not found")
return updated
@router.delete("/{order_id}", response_model=OrderDto)
def remove_order(order_id: int, db: Session = Depends(get_db)):
deleted = delete_order(db, order_id)
if not deleted:
raise HTTPException(404, detail="Order not found")
return deleted

View File

@@ -0,0 +1,132 @@
"""migration1
Revision ID: 7233236dbc53
Revises:
Create Date: 2025-06-18 22:46:12.245919
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '7233236dbc53'
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('faculties',
sa.Column('name', sa.String(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_faculties_id'), 'faculties', ['id'], unique=False)
op.create_table('deans',
sa.Column('faculty_id', sa.Integer(), nullable=True),
sa.Column('last_name', sa.String(), nullable=True),
sa.Column('first_name', sa.String(), nullable=True),
sa.Column('patronymic', sa.String(), nullable=True),
sa.Column('email', sa.String(), nullable=True),
sa.Column('password', sa.String(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['faculty_id'], ['faculties.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_deans_email'), 'deans', ['email'], unique=True)
op.create_index(op.f('ix_deans_id'), 'deans', ['id'], unique=False)
op.create_table('specializations',
sa.Column('name', sa.String(), nullable=True),
sa.Column('code', sa.String(), nullable=True),
sa.Column('faculty_id', sa.Integer(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['faculty_id'], ['faculties.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_specializations_id'), 'specializations', ['id'], unique=False)
op.create_table('groups',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('number', sa.Integer(), nullable=True),
sa.Column('course', sa.Integer(), nullable=True),
sa.Column('max_student_count', sa.Integer(), nullable=True),
sa.Column('specialization_id', sa.Integer(), nullable=True),
sa.Column('count_students', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['specialization_id'], ['specializations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_groups_id'), 'groups', ['id'], unique=False)
op.create_table('learning_plans',
sa.Column('specialization_id', sa.Integer(), nullable=False),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['specialization_id'], ['specializations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_learning_plans_id'), 'learning_plans', ['id'], unique=False)
op.create_table('orders',
sa.Column('order_type', sa.Enum('ADD_STUDENT', 'EXPULSION', 'ACADEMIC_LEAVE', 'CHANGE_SPECIALIZATION', 'NEXT_COURSE', name='ordertype'), nullable=True),
sa.Column('reason', sa.Enum('BY_GENERAL_CONTEST', 'BY_PRIVILEGE', 'BY_CHOICE', 'BY_LEARNING_FAILURE', 'BY_MEDICAL', 'BY_FAMILY', name='reason'), nullable=True),
sa.Column('number', sa.Integer(), nullable=True),
sa.Column('current_dean_id', sa.Integer(), nullable=True),
sa.Column('date', sa.DateTime(), nullable=True),
sa.Column('date_start', sa.DateTime(), nullable=True),
sa.Column('date_end', sa.DateTime(), nullable=True),
sa.Column('new_spec_id', sa.Integer(), nullable=True),
sa.Column('next_course', sa.Integer(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['current_dean_id'], ['deans.id'], ),
sa.ForeignKeyConstraint(['new_spec_id'], ['specializations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_orders_id'), 'orders', ['id'], unique=False)
op.create_table('students',
sa.Column('specialization_id', sa.Integer(), nullable=True),
sa.Column('group_id', sa.Integer(), nullable=True),
sa.Column('status', sa.Enum('STUDYING', 'ACADEMIC_LEAVE', 'EXPELLED', 'GRADUATED', name='status'), nullable=True),
sa.Column('last_name', sa.String(), nullable=True),
sa.Column('first_name', sa.String(), nullable=True),
sa.Column('patronymic', sa.String(), nullable=True),
sa.Column('email', sa.String(), nullable=True),
sa.Column('password', sa.String(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
sa.ForeignKeyConstraint(['specialization_id'], ['specializations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_students_email'), 'students', ['email'], unique=True)
op.create_index(op.f('ix_students_id'), 'students', ['id'], unique=False)
op.create_table('order_student_association',
sa.Column('order_id', sa.Integer(), nullable=True),
sa.Column('student_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['order_id'], ['orders.id'], ),
sa.ForeignKeyConstraint(['student_id'], ['students.id'], )
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('order_student_association')
op.drop_index(op.f('ix_students_id'), table_name='students')
op.drop_index(op.f('ix_students_email'), table_name='students')
op.drop_table('students')
op.drop_index(op.f('ix_orders_id'), table_name='orders')
op.drop_table('orders')
op.drop_index(op.f('ix_learning_plans_id'), table_name='learning_plans')
op.drop_table('learning_plans')
op.drop_index(op.f('ix_groups_id'), table_name='groups')
op.drop_table('groups')
op.drop_index(op.f('ix_specializations_id'), table_name='specializations')
op.drop_table('specializations')
op.drop_index(op.f('ix_deans_id'), table_name='deans')
op.drop_index(op.f('ix_deans_email'), table_name='deans')
op.drop_table('deans')
op.drop_index(op.f('ix_faculties_id'), table_name='faculties')
op.drop_table('faculties')
# ### end Alembic commands ###

View File

@@ -1,247 +0,0 @@
"""migration1
Revision ID: 751209471dc0
Revises:
Create Date: 2025-06-16 16:31:38.736350
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '751209471dc0'
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('faculties',
sa.Column('name', sa.String(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_faculties_id'), 'faculties', ['id'], unique=False)
op.create_table('deans',
sa.Column('faculty_id', sa.Integer(), nullable=True),
sa.Column('last_name', sa.String(), nullable=True),
sa.Column('first_name', sa.String(), nullable=True),
sa.Column('patronymic', sa.String(), nullable=True),
sa.Column('email', sa.String(), nullable=True),
sa.Column('password', sa.String(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['faculty_id'], ['faculties.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_deans_email'), 'deans', ['email'], unique=True)
op.create_index(op.f('ix_deans_id'), 'deans', ['id'], unique=False)
op.create_table('specializations',
sa.Column('name', sa.String(), nullable=True),
sa.Column('code', sa.String(), nullable=True),
sa.Column('faculty_id', sa.Integer(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['faculty_id'], ['faculties.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_specializations_id'), 'specializations', ['id'], unique=False)
op.create_table('academic_leave_orders',
sa.Column('date_start', sa.DateTime(), nullable=True),
sa.Column('date_end', sa.DateTime(), nullable=True),
sa.Column('order_type', sa.Enum('ADD_STUDENT', 'EXPULSION', 'ACADEMIC_LEAVE', 'CHANGE_SPECIALIZATION', 'NEXT_COURSE', name='ordertype'), nullable=True),
sa.Column('reason', sa.Enum('BY_GENERAL_CONTEST', 'BY_PRIVILEGE', 'BY_CHOICE', 'BY_LEARNING_FAILURE', 'BY_MEDICAL', 'BY_FAMILY', name='reason'), nullable=True),
sa.Column('number', sa.Integer(), nullable=True),
sa.Column('current_dean_id', sa.Integer(), nullable=True),
sa.Column('date', sa.DateTime(), nullable=True),
sa.Column('document', sa.LargeBinary(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['current_dean_id'], ['deans.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_academic_leave_orders_id'), 'academic_leave_orders', ['id'], unique=False)
op.create_table('add_students_orders',
sa.Column('order_type', sa.Enum('ADD_STUDENT', 'EXPULSION', 'ACADEMIC_LEAVE', 'CHANGE_SPECIALIZATION', 'NEXT_COURSE', name='ordertype'), nullable=True),
sa.Column('reason', sa.Enum('BY_GENERAL_CONTEST', 'BY_PRIVILEGE', 'BY_CHOICE', 'BY_LEARNING_FAILURE', 'BY_MEDICAL', 'BY_FAMILY', name='reason'), nullable=True),
sa.Column('number', sa.Integer(), nullable=True),
sa.Column('current_dean_id', sa.Integer(), nullable=True),
sa.Column('date', sa.DateTime(), nullable=True),
sa.Column('document', sa.LargeBinary(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['current_dean_id'], ['deans.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_add_students_orders_id'), 'add_students_orders', ['id'], unique=False)
op.create_table('change_specialization_orders',
sa.Column('new_spec_id', sa.Integer(), nullable=True),
sa.Column('order_type', sa.Enum('ADD_STUDENT', 'EXPULSION', 'ACADEMIC_LEAVE', 'CHANGE_SPECIALIZATION', 'NEXT_COURSE', name='ordertype'), nullable=True),
sa.Column('reason', sa.Enum('BY_GENERAL_CONTEST', 'BY_PRIVILEGE', 'BY_CHOICE', 'BY_LEARNING_FAILURE', 'BY_MEDICAL', 'BY_FAMILY', name='reason'), nullable=True),
sa.Column('number', sa.Integer(), nullable=True),
sa.Column('current_dean_id', sa.Integer(), nullable=True),
sa.Column('date', sa.DateTime(), nullable=True),
sa.Column('document', sa.LargeBinary(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['current_dean_id'], ['deans.id'], ),
sa.ForeignKeyConstraint(['new_spec_id'], ['specializations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_change_specialization_orders_id'), 'change_specialization_orders', ['id'], unique=False)
op.create_table('contingent_reports',
sa.Column('current_dean_id', sa.Integer(), nullable=True),
sa.Column('date', sa.DateTime(), nullable=True),
sa.Column('document', sa.LargeBinary(), nullable=True),
sa.Column('file_name', sa.String(), nullable=True),
sa.Column('file_type', sa.String(), nullable=True),
sa.Column('report_type', sa.Enum('SPECIALIZATION', 'GROUP', name='contingentreporttype'), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['current_dean_id'], ['deans.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_contingent_reports_id'), 'contingent_reports', ['id'], unique=False)
op.create_table('expulsion_orders',
sa.Column('order_type', sa.Enum('ADD_STUDENT', 'EXPULSION', 'ACADEMIC_LEAVE', 'CHANGE_SPECIALIZATION', 'NEXT_COURSE', name='ordertype'), nullable=True),
sa.Column('reason', sa.Enum('BY_GENERAL_CONTEST', 'BY_PRIVILEGE', 'BY_CHOICE', 'BY_LEARNING_FAILURE', 'BY_MEDICAL', 'BY_FAMILY', name='reason'), nullable=True),
sa.Column('number', sa.Integer(), nullable=True),
sa.Column('current_dean_id', sa.Integer(), nullable=True),
sa.Column('date', sa.DateTime(), nullable=True),
sa.Column('document', sa.LargeBinary(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['current_dean_id'], ['deans.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_expulsion_orders_id'), 'expulsion_orders', ['id'], unique=False)
op.create_table('groups',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('number', sa.Integer(), nullable=True),
sa.Column('course', sa.Integer(), nullable=True),
sa.Column('max_student_count', sa.Integer(), nullable=True),
sa.Column('specialization_id', sa.Integer(), nullable=True),
sa.Column('count_students', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['specialization_id'], ['specializations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_groups_id'), 'groups', ['id'], unique=False)
op.create_table('learning_plans',
sa.Column('specialization_id', sa.Integer(), nullable=False),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['specialization_id'], ['specializations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_learning_plans_id'), 'learning_plans', ['id'], unique=False)
op.create_table('next_course_orders',
sa.Column('new_course', sa.Integer(), nullable=True),
sa.Column('order_type', sa.Enum('ADD_STUDENT', 'EXPULSION', 'ACADEMIC_LEAVE', 'CHANGE_SPECIALIZATION', 'NEXT_COURSE', name='ordertype'), nullable=True),
sa.Column('reason', sa.Enum('BY_GENERAL_CONTEST', 'BY_PRIVILEGE', 'BY_CHOICE', 'BY_LEARNING_FAILURE', 'BY_MEDICAL', 'BY_FAMILY', name='reason'), nullable=True),
sa.Column('number', sa.Integer(), nullable=True),
sa.Column('current_dean_id', sa.Integer(), nullable=True),
sa.Column('date', sa.DateTime(), nullable=True),
sa.Column('document', sa.LargeBinary(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['current_dean_id'], ['deans.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_next_course_orders_id'), 'next_course_orders', ['id'], unique=False)
op.create_table('contingent_report_groups',
sa.Column('report_id', sa.Integer(), nullable=False),
sa.Column('group_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
sa.ForeignKeyConstraint(['report_id'], ['contingent_reports.id'], ),
sa.PrimaryKeyConstraint('report_id', 'group_id')
)
op.create_table('contingent_report_specializations',
sa.Column('report_id', sa.Integer(), nullable=False),
sa.Column('specialization_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['report_id'], ['contingent_reports.id'], ),
sa.ForeignKeyConstraint(['specialization_id'], ['specializations.id'], ),
sa.PrimaryKeyConstraint('report_id', 'specialization_id')
)
op.create_table('students',
sa.Column('specialization_id', sa.Integer(), nullable=True),
sa.Column('group_id', sa.Integer(), nullable=True),
sa.Column('status', sa.Enum('STUDYING', 'ACADEMIC_LEAVE', 'EXPELLED', 'GRADUATED', name='status'), nullable=True),
sa.Column('last_name', sa.String(), nullable=True),
sa.Column('first_name', sa.String(), nullable=True),
sa.Column('patronymic', sa.String(), nullable=True),
sa.Column('email', sa.String(), nullable=True),
sa.Column('password', sa.String(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
sa.ForeignKeyConstraint(['specialization_id'], ['specializations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_students_email'), 'students', ['email'], unique=True)
op.create_index(op.f('ix_students_id'), 'students', ['id'], unique=False)
op.create_table('academ_student_association',
sa.Column('order_id', sa.Integer(), nullable=True),
sa.Column('student_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['order_id'], ['academic_leave_orders.id'], ),
sa.ForeignKeyConstraint(['student_id'], ['students.id'], )
)
op.create_table('add_student_association',
sa.Column('order_id', sa.Integer(), nullable=True),
sa.Column('student_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['order_id'], ['add_students_orders.id'], ),
sa.ForeignKeyConstraint(['student_id'], ['students.id'], )
)
op.create_table('change_student_association',
sa.Column('order_id', sa.Integer(), nullable=True),
sa.Column('student_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['order_id'], ['change_specialization_orders.id'], ),
sa.ForeignKeyConstraint(['student_id'], ['students.id'], )
)
op.create_table('expulsion_student_association',
sa.Column('order_id', sa.Integer(), nullable=True),
sa.Column('student_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['order_id'], ['expulsion_orders.id'], ),
sa.ForeignKeyConstraint(['student_id'], ['students.id'], )
)
op.create_table('next_student_association',
sa.Column('order_id', sa.Integer(), nullable=True),
sa.Column('student_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['order_id'], ['next_course_orders.id'], ),
sa.ForeignKeyConstraint(['student_id'], ['students.id'], )
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('next_student_association')
op.drop_table('expulsion_student_association')
op.drop_table('change_student_association')
op.drop_table('add_student_association')
op.drop_table('academ_student_association')
op.drop_index(op.f('ix_students_id'), table_name='students')
op.drop_index(op.f('ix_students_email'), table_name='students')
op.drop_table('students')
op.drop_table('contingent_report_specializations')
op.drop_table('contingent_report_groups')
op.drop_index(op.f('ix_next_course_orders_id'), table_name='next_course_orders')
op.drop_table('next_course_orders')
op.drop_index(op.f('ix_learning_plans_id'), table_name='learning_plans')
op.drop_table('learning_plans')
op.drop_index(op.f('ix_groups_id'), table_name='groups')
op.drop_table('groups')
op.drop_index(op.f('ix_expulsion_orders_id'), table_name='expulsion_orders')
op.drop_table('expulsion_orders')
op.drop_index(op.f('ix_contingent_reports_id'), table_name='contingent_reports')
op.drop_table('contingent_reports')
op.drop_index(op.f('ix_change_specialization_orders_id'), table_name='change_specialization_orders')
op.drop_table('change_specialization_orders')
op.drop_index(op.f('ix_add_students_orders_id'), table_name='add_students_orders')
op.drop_table('add_students_orders')
op.drop_index(op.f('ix_academic_leave_orders_id'), table_name='academic_leave_orders')
op.drop_table('academic_leave_orders')
op.drop_index(op.f('ix_specializations_id'), table_name='specializations')
op.drop_table('specializations')
op.drop_index(op.f('ix_deans_id'), table_name='deans')
op.drop_index(op.f('ix_deans_email'), table_name='deans')
op.drop_table('deans')
op.drop_index(op.f('ix_faculties_id'), table_name='faculties')
op.drop_table('faculties')
# ### end Alembic commands ###