diff --git a/Academic_Performance/Academic_Performance/Academic_Performance.csproj b/Academic_Performance/Academic_Performance/Academic_Performance.csproj index cd889fa..cd77ad5 100644 --- a/Academic_Performance/Academic_Performance/Academic_Performance.csproj +++ b/Academic_Performance/Academic_Performance/Academic_Performance.csproj @@ -10,6 +10,7 @@ + diff --git a/Academic_Performance/Academic_Performance/Entities/Mark.cs b/Academic_Performance/Academic_Performance/Entities/Mark.cs index ee78460..f899c1d 100644 --- a/Academic_Performance/Academic_Performance/Entities/Mark.cs +++ b/Academic_Performance/Academic_Performance/Entities/Mark.cs @@ -11,17 +11,21 @@ namespace Academic_Performance.Entities { public int Id { get; private set; } public int StudentId { get; private set; } - public int StatmentTeacherId { get; private set; } - public int StatmentSubjectId { get; private set; } + /// public int TeachersId { get; private set; } + /// + ///public int SubjectId { get; private set; } + /// public string Value { get; private set; } = string.Empty; - public static Mark CreateElement(int id, int studentId, int statmentSubjectId, int statmentTeacherId,string value) + public static Mark CreateElement(int id, + int studentId,///int teacherId, int subjectId, + string value) { return new Mark { Id = id, StudentId = studentId, - StatmentSubjectId = statmentSubjectId, - StatmentTeacherId = statmentTeacherId, + /// TeachersId = teacherId, + /// SubjectId = subjectId, Value = value }; } diff --git a/Academic_Performance/Academic_Performance/Entities/Statement.cs b/Academic_Performance/Academic_Performance/Entities/Statement.cs index 55a81c7..c0312ce 100644 --- a/Academic_Performance/Academic_Performance/Entities/Statement.cs +++ b/Academic_Performance/Academic_Performance/Entities/Statement.cs @@ -16,7 +16,8 @@ namespace Academic_Performance.Entities public DateTime Date { get; private set; } public IEnumerable Mark{ get; private set; } = []; public static Statement CreateOperation(int id, int subjectId, int teacherId, IEnumerable mark) - {return new Statement + { + return new Statement { Id = id, SubjectId = subjectId, @@ -25,5 +26,20 @@ namespace Academic_Performance.Entities Mark = mark }; } + + public static Statement CreateOperation(TempMarks tempmarks, IEnumerable mark) + { + return new Statement + { + Id = tempmarks.Id, + SubjectId = tempmarks.SubjectId, + TeacherId = tempmarks.TeacherId, + Date = tempmarks.Date, + Mark = mark + }; + } + + + } } diff --git a/Academic_Performance/Academic_Performance/Entities/Student.cs b/Academic_Performance/Academic_Performance/Entities/Student.cs index 3723a62..ee23084 100644 --- a/Academic_Performance/Academic_Performance/Entities/Student.cs +++ b/Academic_Performance/Academic_Performance/Entities/Student.cs @@ -10,7 +10,7 @@ namespace Academic_Performance.Entities public class Student { public int Id{ get; private set; } - public Groupp? Groupp { get; private set; } + public Groupp Groupp { get; private set; } public string Name { get; private set; } = string.Empty; public string Flow { get; private set; } = string.Empty; public static Student CreateEntity(int id, string name,string flow, Groupp groupp) diff --git a/Academic_Performance/Academic_Performance/Entities/TempMarks.cs b/Academic_Performance/Academic_Performance/Entities/TempMarks.cs new file mode 100644 index 0000000..0eaac0b --- /dev/null +++ b/Academic_Performance/Academic_Performance/Entities/TempMarks.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Academic_Performance.Entities; + +public class TempMarks +{ + public int Id { get; private set; } + public int StudentId { get; private set; } + public int TeacherId { get; private set; } + public int SubjectId { get; private set; } + public DateTime Date { get; private set; } + public string Value { get; private set; } = string.Empty; +} diff --git a/Academic_Performance/Academic_Performance/Form1.Designer.cs b/Academic_Performance/Academic_Performance/Form1.Designer.cs index a444a28..6c4086d 100644 --- a/Academic_Performance/Academic_Performance/Form1.Designer.cs +++ b/Academic_Performance/Academic_Performance/Form1.Designer.cs @@ -37,6 +37,8 @@ добавлениеToolStripMenuItem = new ToolStripMenuItem(); ведомостьToolStripMenuItem = new ToolStripMenuItem(); отчетыToolStripMenuItem = new ToolStripMenuItem(); + DirectoryReportToolStripMenuItem = new ToolStripMenuItem(); + таблицаСОценкамиToolStripMenuItem = new ToolStripMenuItem(); menuStrip.SuspendLayout(); SuspendLayout(); // @@ -61,21 +63,21 @@ // studentToolStripMenuItem // studentToolStripMenuItem.Name = "studentToolStripMenuItem"; - studentToolStripMenuItem.Size = new Size(224, 26); + studentToolStripMenuItem.Size = new Size(201, 26); studentToolStripMenuItem.Text = "Студенты"; studentToolStripMenuItem.Click += studentToolStripMenuItem_Click; // // TeacherToolStripMenuItem // TeacherToolStripMenuItem.Name = "TeacherToolStripMenuItem"; - TeacherToolStripMenuItem.Size = new Size(224, 26); + TeacherToolStripMenuItem.Size = new Size(201, 26); TeacherToolStripMenuItem.Text = "Преподаватели"; TeacherToolStripMenuItem.Click += TeacherToolStripMenuItem_Click; // // SubToolStripMenuItem // SubToolStripMenuItem.Name = "SubToolStripMenuItem"; - SubToolStripMenuItem.Size = new Size(224, 26); + SubToolStripMenuItem.Size = new Size(201, 26); SubToolStripMenuItem.Text = "Предметы"; SubToolStripMenuItem.Click += SubToolStripMenuItem_Click; // @@ -89,23 +91,40 @@ // добавлениеToolStripMenuItem // добавлениеToolStripMenuItem.Name = "добавлениеToolStripMenuItem"; - добавлениеToolStripMenuItem.Size = new Size(224, 26); + добавлениеToolStripMenuItem.Size = new Size(167, 26); добавлениеToolStripMenuItem.Text = "Ведомость"; добавлениеToolStripMenuItem.Click += добавлениеToolStripMenuItem_Click; // // ведомостьToolStripMenuItem // ведомостьToolStripMenuItem.Name = "ведомостьToolStripMenuItem"; - ведомостьToolStripMenuItem.Size = new Size(224, 26); + ведомостьToolStripMenuItem.Size = new Size(167, 26); ведомостьToolStripMenuItem.Text = "Приказ"; ведомостьToolStripMenuItem.Click += ведомостьToolStripMenuItem_Click; // // отчетыToolStripMenuItem // + отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { DirectoryReportToolStripMenuItem, таблицаСОценкамиToolStripMenuItem }); отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem"; отчетыToolStripMenuItem.Size = new Size(73, 24); отчетыToolStripMenuItem.Text = "Отчеты"; // + // DirectoryReportToolStripMenuItem + // + DirectoryReportToolStripMenuItem.Name = "DirectoryReportToolStripMenuItem"; + DirectoryReportToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.W; + DirectoryReportToolStripMenuItem.Size = new Size(354, 26); + DirectoryReportToolStripMenuItem.Text = "Документ со справочниками "; + DirectoryReportToolStripMenuItem.Click += DirectoryReportToolStripMenuItem_Click; + // + // таблицаСОценкамиToolStripMenuItem + // + таблицаСОценкамиToolStripMenuItem.Name = "таблицаСОценкамиToolStripMenuItem"; + таблицаСОценкамиToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.E; + таблицаСОценкамиToolStripMenuItem.Size = new Size(354, 26); + таблицаСОценкамиToolStripMenuItem.Text = "Таблица с оценками"; + таблицаСОценкамиToolStripMenuItem.Click += таблицаСОценкамиToolStripMenuItem_Click; + // // Form1 // AutoScaleDimensions = new SizeF(8F, 20F); @@ -136,5 +155,7 @@ private ToolStripMenuItem добавлениеToolStripMenuItem; private ToolStripMenuItem отчетыToolStripMenuItem; private ToolStripMenuItem ведомостьToolStripMenuItem; + private ToolStripMenuItem DirectoryReportToolStripMenuItem; + private ToolStripMenuItem таблицаСОценкамиToolStripMenuItem; } } diff --git a/Academic_Performance/Academic_Performance/Form1.cs b/Academic_Performance/Academic_Performance/Form1.cs index 0a1597e..5e82611 100644 --- a/Academic_Performance/Academic_Performance/Form1.cs +++ b/Academic_Performance/Academic_Performance/Form1.cs @@ -83,5 +83,31 @@ namespace Academic_Performance MessageBox.Show(ex.Message, " ", MessageBoxButtons.OK, MessageBoxIcon.Error); } } + + private void DirectoryReportToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + _container.Resolve().ShowDialog(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, " ", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + _container.Resolve().ShowDialog(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, " ", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } } } diff --git a/Academic_Performance/Academic_Performance/Forms/FormDirectoryReport.Designer.cs b/Academic_Performance/Academic_Performance/Forms/FormDirectoryReport.Designer.cs new file mode 100644 index 0000000..fc90857 --- /dev/null +++ b/Academic_Performance/Academic_Performance/Forms/FormDirectoryReport.Designer.cs @@ -0,0 +1,99 @@ +namespace Academic_Performance.Forms +{ + partial class FormDirectoryReport + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + checkBoxStudent = new CheckBox(); + checkBoxTeacher = new CheckBox(); + checkBoxSubject = new CheckBox(); + buttonCreate = new Button(); + SuspendLayout(); + // + // checkBoxStudent + // + checkBoxStudent.AutoSize = true; + checkBoxStudent.Location = new Point(28, 40); + checkBoxStudent.Name = "checkBoxStudent"; + checkBoxStudent.Size = new Size(95, 24); + checkBoxStudent.TabIndex = 0; + checkBoxStudent.Text = "Cтуденты"; + checkBoxStudent.UseVisualStyleBackColor = true; + // + // checkBoxTeacher + // + checkBoxTeacher.AutoSize = true; + checkBoxTeacher.Location = new Point(28, 106); + checkBoxTeacher.Name = "checkBoxTeacher"; + checkBoxTeacher.Size = new Size(140, 24); + checkBoxTeacher.TabIndex = 1; + checkBoxTeacher.Text = "Преподаватели"; + checkBoxTeacher.UseVisualStyleBackColor = true; + // + // checkBoxSubject + // + checkBoxSubject.AutoSize = true; + checkBoxSubject.Location = new Point(28, 157); + checkBoxSubject.Name = "checkBoxSubject"; + checkBoxSubject.Size = new Size(103, 24); + checkBoxSubject.TabIndex = 2; + checkBoxSubject.Text = "Предметы"; + checkBoxSubject.UseVisualStyleBackColor = true; + // + // buttonCreate + // + buttonCreate.Location = new Point(429, 106); + buttonCreate.Name = "buttonCreate"; + buttonCreate.Size = new Size(149, 29); + buttonCreate.TabIndex = 3; + buttonCreate.Text = "Сформировать"; + buttonCreate.UseVisualStyleBackColor = true; + buttonCreate.Click += buttonCreate_Click; + // + // FormDirectoryReport + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(608, 215); + Controls.Add(buttonCreate); + Controls.Add(checkBoxSubject); + Controls.Add(checkBoxTeacher); + Controls.Add(checkBoxStudent); + Name = "FormDirectoryReport"; + Text = "FormDirectoryReport"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private CheckBox checkBoxStudent; + private CheckBox checkBoxTeacher; + private CheckBox checkBoxSubject; + private Button buttonCreate; + } +} \ No newline at end of file diff --git a/Academic_Performance/Academic_Performance/Forms/FormDirectoryReport.cs b/Academic_Performance/Academic_Performance/Forms/FormDirectoryReport.cs new file mode 100644 index 0000000..6322ea5 --- /dev/null +++ b/Academic_Performance/Academic_Performance/Forms/FormDirectoryReport.cs @@ -0,0 +1,61 @@ +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 Academic_Performance.Reports; +using Unity; + +namespace Academic_Performance.Forms +{ + public partial class FormDirectoryReport : Form + { + private readonly IUnityContainer _container; + public FormDirectoryReport(IUnityContainer container) + { + InitializeComponent(); + _container = container ?? throw new ArgumentNullException(nameof(container)); + } + + private void buttonCreate_Click(object sender, EventArgs e) + { + + + try + { + if (!checkBoxTeacher.Checked && !checkBoxStudent.Checked && !checkBoxSubject.Checked) + { + throw new Exception("Не выбран ни один справочник для выгрузки"); + } + var sfd = new SaveFileDialog() + { + Filter = "Docx Files | *.docx" + }; + if (sfd.ShowDialog() != DialogResult.OK) + { + throw new Exception("Не выбран файла для отчета"); + } + if (_container.Resolve().CreateDoc(sfd.FileName, checkBoxTeacher.Checked, + checkBoxStudent.Checked, checkBoxSubject.Checked)) + { + MessageBox.Show("Документ сформирован", "Формирование документа", + MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else + { + MessageBox.Show("Возникли ошибки при формировании документа.Подробности в логах", + "Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка при создании отчета", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + } +} diff --git a/Academic_Performance/Academic_Performance/Forms/FormDirectoryReport.resx b/Academic_Performance/Academic_Performance/Forms/FormDirectoryReport.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/Academic_Performance/Academic_Performance/Forms/FormDirectoryReport.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Academic_Performance/Academic_Performance/Forms/FormMark.cs b/Academic_Performance/Academic_Performance/Forms/FormMark.cs index 2073370..39d18c7 100644 --- a/Academic_Performance/Academic_Performance/Forms/FormMark.cs +++ b/Academic_Performance/Academic_Performance/Forms/FormMark.cs @@ -66,7 +66,8 @@ namespace Academic_Performance.Forms continue; } - list.Add(Mark.CreateElement(0, Convert.ToInt32(row.Cells["ColStudent"].Value), (int)comboBoxSubject.SelectedValue!,(int)comboBoxTeacher.SelectedValue!, + list.Add(Mark.CreateElement(0, Convert.ToInt32(row.Cells["ColStudent"].Value), + ///(int)comboBoxSubject.SelectedValue!,(int)comboBoxTeacher.SelectedValue!, row.Cells["ColValue"].Value.ToString() )); } diff --git a/Academic_Performance/Academic_Performance/Forms/ReportMarks.Designer.cs b/Academic_Performance/Academic_Performance/Forms/ReportMarks.Designer.cs new file mode 100644 index 0000000..a08983a --- /dev/null +++ b/Academic_Performance/Academic_Performance/Forms/ReportMarks.Designer.cs @@ -0,0 +1,164 @@ +namespace Academic_Performance.Forms +{ + partial class ReportMarks + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + dateTimePickerStart = new DateTimePicker(); + dateTimePickerEnd = new DateTimePicker(); + label1 = new Label(); + label2 = new Label(); + label3 = new Label(); + label4 = new Label(); + comboBoxStudent = new ComboBox(); + textBoxFile = new TextBox(); + buttonFile = new Button(); + buttonSave = new Button(); + SuspendLayout(); + // + // dateTimePickerStart + // + dateTimePickerStart.Location = new Point(160, 225); + dateTimePickerStart.Name = "dateTimePickerStart"; + dateTimePickerStart.Size = new Size(250, 27); + dateTimePickerStart.TabIndex = 0; + // + // dateTimePickerEnd + // + dateTimePickerEnd.Location = new Point(160, 308); + dateTimePickerEnd.Name = "dateTimePickerEnd"; + dateTimePickerEnd.Size = new Size(250, 27); + dateTimePickerEnd.TabIndex = 1; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(28, 225); + label1.Name = "label1"; + label1.Size = new Size(94, 20); + label1.TabIndex = 2; + label1.Text = "Дата начала"; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new Point(28, 308); + label2.Name = "label2"; + label2.Size = new Size(87, 20); + label2.TabIndex = 3; + label2.Text = "Дата конца"; + // + // label3 + // + label3.AutoSize = true; + label3.Location = new Point(28, 65); + label3.Name = "label3"; + label3.Size = new Size(112, 20); + label3.TabIndex = 4; + label3.Text = "Путь до файла:"; + // + // label4 + // + label4.AutoSize = true; + label4.Location = new Point(28, 148); + label4.Name = "label4"; + label4.Size = new Size(107, 20); + label4.TabIndex = 5; + label4.Text = "ФИО Студента"; + // + // comboBoxStudent + // + comboBoxStudent.FormattingEnabled = true; + comboBoxStudent.Location = new Point(160, 148); + comboBoxStudent.Name = "comboBoxStudent"; + comboBoxStudent.Size = new Size(250, 28); + comboBoxStudent.TabIndex = 6; + // + // textBoxFile + // + textBoxFile.Location = new Point(164, 65); + textBoxFile.Name = "textBoxFile"; + textBoxFile.ReadOnly = true; + textBoxFile.Size = new Size(246, 27); + textBoxFile.TabIndex = 7; + // + // buttonFile + // + buttonFile.Location = new Point(427, 65); + buttonFile.Name = "buttonFile"; + buttonFile.Size = new Size(39, 29); + buttonFile.TabIndex = 8; + buttonFile.Text = "..."; + buttonFile.UseVisualStyleBackColor = true; + buttonFile.Click += buttonFile_Click; + // + // buttonSave + // + buttonSave.Location = new Point(164, 386); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(164, 29); + buttonSave.TabIndex = 9; + buttonSave.Text = "Сформировать"; + buttonSave.UseVisualStyleBackColor = true; + buttonSave.Click += buttonSave_Click; + // + // ReportMarks + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(525, 450); + Controls.Add(buttonSave); + Controls.Add(buttonFile); + Controls.Add(textBoxFile); + Controls.Add(comboBoxStudent); + Controls.Add(label4); + Controls.Add(label3); + Controls.Add(label2); + Controls.Add(label1); + Controls.Add(dateTimePickerEnd); + Controls.Add(dateTimePickerStart); + Name = "ReportMarks"; + StartPosition = FormStartPosition.CenterScreen; + Text = "ReportMarks"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private DateTimePicker dateTimePickerStart; + private DateTimePicker dateTimePickerEnd; + private Label label1; + private Label label2; + private Label label3; + private Label label4; + private ComboBox comboBoxStudent; + private TextBox textBoxFile; + private Button buttonFile; + private Button buttonSave; + } +} \ No newline at end of file diff --git a/Academic_Performance/Academic_Performance/Forms/ReportMarks.cs b/Academic_Performance/Academic_Performance/Forms/ReportMarks.cs new file mode 100644 index 0000000..deda84b --- /dev/null +++ b/Academic_Performance/Academic_Performance/Forms/ReportMarks.cs @@ -0,0 +1,86 @@ +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 Academic_Performance.Reports; +using Academic_Performance.Repositories; +using Unity; + +namespace Academic_Performance.Forms +{ + public partial class ReportMarks : Form + { + private readonly IUnityContainer _container; + public ReportMarks(IUnityContainer container, IStudentRepository studentRepository) + { + + InitializeComponent(); + _container = container ?? + throw new ArgumentNullException(nameof(container)); + comboBoxStudent.DataSource = studentRepository.ReadStudent(); + comboBoxStudent.DisplayMember = "Name"; + comboBoxStudent.ValueMember = "Id"; + + } + + private void buttonSave_Click(object sender, EventArgs e) + { + try + { + if (string.IsNullOrWhiteSpace(textBoxFile.Text)) + { + throw new Exception("Отсутствует имя файла для отчета"); + } + if (comboBoxStudent.SelectedIndex < 0) + { + throw new Exception("Не выбран студент"); + } + + if (dateTimePickerEnd.Value <= + dateTimePickerStart.Value) + { + throw new Exception("Дата начала должна быть раньше даты окончания"); + } + if + (_container.Resolve().CreateTable(textBoxFile.Text, + (int)comboBoxStudent.SelectedValue!, + dateTimePickerStart.Value, dateTimePickerEnd.Value)) + { + MessageBox.Show("Документ сформирован", + "Формирование документа", + MessageBoxButtons.OK, + MessageBoxIcon.Information); + } + else + { + MessageBox.Show("Возникли ошибки при формировании документа.Подробности в логах", + "Формирование документа", + MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка при создании очета", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void buttonFile_Click(object sender, EventArgs e) + { + var sfd = new SaveFileDialog() + { + Filter = "Excel Files | *.xlsx" + }; + if (sfd.ShowDialog() != DialogResult.OK) + { + return; + } + textBoxFile.Text = sfd.FileName; + } + } +} diff --git a/Academic_Performance/Academic_Performance/Forms/ReportMarks.resx b/Academic_Performance/Academic_Performance/Forms/ReportMarks.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/Academic_Performance/Academic_Performance/Forms/ReportMarks.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Academic_Performance/Academic_Performance/Reports/DocReport.cs b/Academic_Performance/Academic_Performance/Reports/DocReport.cs new file mode 100644 index 0000000..b2d62a7 --- /dev/null +++ b/Academic_Performance/Academic_Performance/Reports/DocReport.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Academic_Performance.Repositories; +using Microsoft.Extensions.Logging; + +namespace Academic_Performance.Reports; + +public class DocReport +{ + private readonly IStudentRepository _studentRepository; + private readonly ISubjectRepository _subjectRepository; + private readonly ITeacherRepository _teacherRepository; + + private readonly ILogger _logger; + + public DocReport(IStudentRepository studentRepository, ISubjectRepository subjectRepository, + ITeacherRepository teacherRepository,ILogger logger) + { + _studentRepository = studentRepository ?? throw new ArgumentNullException(nameof(studentRepository)); + _subjectRepository = subjectRepository ?? throw new ArgumentNullException(nameof(subjectRepository)); + _teacherRepository = teacherRepository ?? throw new ArgumentNullException(nameof(teacherRepository)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + public bool CreateDoc(string filePath, bool includeTeachers, bool includeSubjects, bool includeStudents) + { + try + { + var builder = new WordBuilder(filePath).AddHeader("Документ со справочниками"); + if (includeStudents) + { + builder.AddParagraph("Студенты").AddTable([3500, 3500,3500], GetGetStudentById()); + } + if (includeTeachers) + { + builder.AddParagraph("Преподаватели").AddTable([3500], GetTeacherById()); + } + if (includeSubjects) + { + builder.AddParagraph("Предменты").AddTable([1200], GetSubjectById()); + } + builder.Build(); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при формировании документа"); + return false; + } + } + + private List GetGetStudentById() + { + return [ + ["ФИО Студента", "Поток", "Группа"], + .. _studentRepository + .ReadStudent() + .Select(x => new string[] { x.Name, x.Flow, x.Groupp.ToString() }), + ]; + } + + + private List GetTeacherById() + { + return [ + ["ФИO Преподавателя"], + .. _teacherRepository + .ReadTeachers() + .Select(x => new string[] { x.Name}), + ]; + } + + + private List GetSubjectById() + { + return [ + ["Название"], + .._subjectRepository + .ReadSubject() + .Select(x => new string[] { x.Name }), + ]; + } + +} diff --git a/Academic_Performance/Academic_Performance/Reports/ExcelBuilder.cs b/Academic_Performance/Academic_Performance/Reports/ExcelBuilder.cs new file mode 100644 index 0000000..5b1e74a --- /dev/null +++ b/Academic_Performance/Academic_Performance/Reports/ExcelBuilder.cs @@ -0,0 +1,335 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Spreadsheet; +using DocumentFormat.OpenXml; + +namespace Academic_Performance.Reports; + + +public class ExcelBuilder +{ + private readonly string _filePath; + + private readonly SheetData _sheetData; + + private readonly MergeCells _mergeCells; + + private readonly Columns _columns; + + private uint _rowIndex = 0; + + public ExcelBuilder(string filePath) + { + if (string.IsNullOrWhiteSpace(filePath)) + { + throw new ArgumentNullException(nameof(filePath)); + } + + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + + _filePath = filePath; + _sheetData = new SheetData(); + _mergeCells = new MergeCells(); + _columns = new Columns(); + _rowIndex = 1; + } + + public ExcelBuilder AddHeader(string header, int startIndex, int cnt) + { + CreateCell(startIndex, _rowIndex, header, StyleIndex.BoldTextWithoutBorder); + for (int i = startIndex + 1; i < startIndex + cnt; ++i) + { + CreateCell(i, _rowIndex, "", StyleIndex.SimpleTextWithoutBorder); + } + + _mergeCells.Append(new MergeCell() + { + Reference = new StringValue($"{GetExcelColumnName(startIndex)}{_rowIndex}:{GetExcelColumnName(startIndex + cnt - 1)}{_rowIndex}") + }); _rowIndex++; + + return this; + } + public ExcelBuilder AddParagraph(string text, int columnIndex) + { + CreateCell(columnIndex, _rowIndex++, text, StyleIndex.SimpleTextWithoutBorder); + return this; + } + + public ExcelBuilder AddTable(int[] columnsWidths, List data) + { + if (columnsWidths == null || columnsWidths.Length == 0) + { + throw new ArgumentNullException(nameof(columnsWidths)); + } + + if (data == null || data.Count == 0) + { + throw new ArgumentNullException(nameof(data)); + } + + if (data.Any(x => x.Length != columnsWidths.Length)) + { + throw new InvalidOperationException("widths.Length != data.Length"); + } + + uint counter = 1; + int coef = 2; + _columns.Append(columnsWidths.Select(x => new Column + { + Min = counter, + Max = counter++, + Width = x * coef, + CustomWidth = true + })); + + for (var j = 0; j < data.First().Length; ++j) + { + CreateCell(j, _rowIndex, data.First()[j], StyleIndex.BoldTextWithBorder); + } + + _rowIndex++; + for (var i = 1; i < data.Count - 1; ++i) + { + for (var j = 0; j < data[i].Length; ++j) + { + CreateCell(j, _rowIndex, data[i][j], StyleIndex.SimpleTextWithBorder); + } + + _rowIndex++; + } + + for (var j = 0; j < data.Last().Length; ++j) + { + CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorder); + } + + _rowIndex++; + return this; + } + + public void Build() + { + using var spreadsheetDocument = SpreadsheetDocument.Create(_filePath, SpreadsheetDocumentType.Workbook); + var workbookpart = spreadsheetDocument.AddWorkbookPart(); + GenerateStyle(workbookpart); + workbookpart.Workbook = new Workbook(); + var worksheetPart = workbookpart.AddNewPart(); + worksheetPart.Worksheet = new Worksheet(); + if (_columns.HasChildren) + { + worksheetPart.Worksheet.Append(_columns); + } + + worksheetPart.Worksheet.Append(_sheetData); + + var sheets = spreadsheetDocument.WorkbookPart!.Workbook.AppendChild(new Sheets()); + + var sheet = new Sheet() + { + Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), + SheetId = 1, + Name = "Лист 1" + }; + + sheets.Append(sheet); + if (_mergeCells.HasChildren) + { + worksheetPart.Worksheet.InsertAfter(_mergeCells, worksheetPart.Worksheet.Elements().First()); + } + } + + private static void GenerateStyle(WorkbookPart workbookPart) + { + var workbookStylesPart = workbookPart.AddNewPart(); + workbookStylesPart.Stylesheet = new Stylesheet(); + + var fonts = new Fonts() + { + Count = 2, + KnownFonts = BooleanValue.FromBoolean(true) + }; + + fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font + { + FontSize = new FontSize() { Val = 11 }, + FontName = new FontName() { Val = "Calibri" }, + FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 }, + FontScheme = new FontScheme() { Val = new EnumValue(FontSchemeValues.Minor) } + }); + + // Жирный шрифт. + fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font + { + FontSize = new FontSize() { Val = 11 }, + FontName = new FontName() { Val = "Calibri" }, + FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 }, + FontScheme = new FontScheme() + { + Val = new EnumValue(FontSchemeValues.Minor) + }, + Bold = new Bold() { Val = true } + }); + workbookStylesPart.Stylesheet.Append(fonts); + + // Default Fill. + var fills = new Fills() { Count = 1 }; + fills.Append(new Fill + { + PatternFill = new PatternFill() { PatternType = new EnumValue(PatternValues.None) } + }); + workbookStylesPart.Stylesheet.Append(fills); + + // Default Border. + var borders = new Borders() { Count = 2 }; + borders.Append(new Border + { + LeftBorder = new LeftBorder(), + RightBorder = new RightBorder(), + TopBorder = new TopBorder(), + BottomBorder = new BottomBorder(), + DiagonalBorder = new DiagonalBorder() + }); + + // Настройка с границами. + borders.Append(new Border + { + LeftBorder = new LeftBorder() { Style = BorderStyleValues.Thin }, + RightBorder = new RightBorder() { Style = BorderStyleValues.Thin }, + TopBorder = new TopBorder() { Style = BorderStyleValues.Thin }, + BottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin }, + DiagonalBorder = new DiagonalBorder() + }); + workbookStylesPart.Stylesheet.Append(borders); + + // Default cell format and a date cell format. + var cellFormats = new CellFormats() { Count = 4 }; + cellFormats.Append(new CellFormat + { + NumberFormatId = 0, + FormatId = 0, + FontId = 0, + BorderId = 0, + FillId = 0, + Alignment = new Alignment() + { + Horizontal = HorizontalAlignmentValues.Left, + Vertical = VerticalAlignmentValues.Center, + WrapText = true + } + }); + + // Форматы. + cellFormats.Append(new CellFormat + { + NumberFormatId = 0, + FormatId = 0, + FontId = 0, + BorderId = 1, + FillId = 0, + Alignment = new Alignment() + { + Horizontal = HorizontalAlignmentValues.Right, + Vertical = VerticalAlignmentValues.Center, + WrapText = true + } + }); + cellFormats.Append(new CellFormat + { + NumberFormatId = 0, + FormatId = 0, + FontId = 1, + BorderId = 0, + FillId = 0, + Alignment = new Alignment() + { + Horizontal = HorizontalAlignmentValues.Center, + Vertical = VerticalAlignmentValues.Center, + WrapText = true + } + }); + cellFormats.Append(new CellFormat + { + NumberFormatId = 0, + FormatId = 0, + FontId = 1, + BorderId = 1, + FillId = 0, + Alignment = new Alignment() + { + Horizontal = HorizontalAlignmentValues.Center, + Vertical = VerticalAlignmentValues.Center, + WrapText = true + } + }); + workbookStylesPart.Stylesheet.Append(cellFormats); + } + private enum StyleIndex + { + SimpleTextWithoutBorder = 0, + SimpleTextWithBorder = 1, + BoldTextWithoutBorder = 2, + BoldTextWithBorder = 3, + } + + private void CreateCell(int columnIndex, uint rowIndex, string text, StyleIndex styleIndex) + { + var columnName = GetExcelColumnName(columnIndex); + var cellReference = columnName + rowIndex; + var row = _sheetData.Elements().FirstOrDefault(r => r.RowIndex! == rowIndex); + + if (row == null) + { + row = new Row() { RowIndex = rowIndex }; + _sheetData.Append(row); + } + + var newCell = row.Elements() + .FirstOrDefault(c => c.CellReference != null && c.CellReference.Value == columnName + rowIndex); + if (newCell == null) + { + Cell? refCell = null; + foreach (Cell cell in row.Elements()) + { + if (cell.CellReference?.Value != null && cell.CellReference.Value.Length == cellReference.Length) + { + if (string.Compare(cell.CellReference.Value, cellReference, true) > 0) + { + refCell = cell; + break; + } + } + } + + newCell = new Cell() { CellReference = cellReference }; + row.InsertBefore(newCell, refCell); + } + + newCell.CellValue = new CellValue(text); + newCell.DataType = CellValues.String; + newCell.StyleIndex = (uint)styleIndex; + } + + private static string GetExcelColumnName(int columnNumber) + { + columnNumber += 1; + int dividend = columnNumber; + string columnName = string.Empty; + int modulo; + + while (dividend > 0) + { + modulo = (dividend - 1) % 26; + columnName = Convert.ToChar(65 + modulo).ToString() + columnName; + dividend = (dividend - modulo) / 26; + } + + return columnName; + } +} \ No newline at end of file diff --git a/Academic_Performance/Academic_Performance/Reports/TableReport.cs b/Academic_Performance/Academic_Performance/Reports/TableReport.cs new file mode 100644 index 0000000..151098b --- /dev/null +++ b/Academic_Performance/Academic_Performance/Reports/TableReport.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Academic_Performance.Entities; +using Academic_Performance.Repositories; +using Academic_Performance.Repositories.Implementations; +using Microsoft.Extensions.Logging; + +namespace Academic_Performance.Reports; + +public class TableReport +{ + private readonly IStatementRepository _statementRepository; + private readonly IOrderRepository _orderRepository; + private readonly ISubjectRepository _subjectRepository; + private readonly ITeacherRepository _teacherRepository; + private readonly ILogger _logger; + internal static readonly string[] item = ["Преподаватель", "Дата", "Предмет", "Оценка"]; + + public TableReport(IStatementRepository statementRepository,IOrderRepository orderRepository, + ISubjectRepository subjectRepository,ILogger logger, ITeacherRepository teacherRepository) + { + _teacherRepository = teacherRepository ?? throw new ArgumentNullException(nameof(teacherRepository)); + _statementRepository = statementRepository ?? throw new ArgumentNullException(nameof(statementRepository)); + _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _subjectRepository = subjectRepository ?? throw new ArgumentNullException(nameof(subjectRepository)); + } + + public bool CreateTable(string filePath, int studentId, DateTime startDate, DateTime endDate) + { + try + { + new ExcelBuilder(filePath) + .AddHeader("Сводка по успеваемости ", 0,4) + .AddParagraph("за период", 0) + .AddTable([15,15,15,15], GetData(studentId,startDate, endDate)) + .Build(); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при формировании документа"); + return false; + } + } + + private List GetData(int studentId, DateTime startDate, DateTime endDate) + { + var subjects = _subjectRepository + .ReadSubject() + .ToDictionary(s => s.Id, s => s.Name); + var teacher = _teacherRepository + .ReadTeachers() + .ToDictionary(p => p.Id, p => $"{p.Name}"); + // Получаем оценки за диапазон дат для указанного студента + var markss= _statementRepository + .ReadStatement() + .Where(g => g.Date >= startDate && g.Date <= endDate + && g.Mark.Any(sg => sg.StudentId == studentId)) + .Select(g => new + {Date = g.Date, Subject = subjects.TryGetValue(g.SubjectId, out var subject) ? subject : "Неизвестный предмет", + + Value = long.TryParse(g.Mark.First(sg => sg.StudentId == studentId).Value, out var gradeValue) ? gradeValue : 0, + Teacher = teacher.TryGetValue(g.TeacherId, out var prof) ? prof : "Неизвестный преподаватель" + }) + .ToList(); + + + var averageGrade = markss.Any() ? markss.Average(g => g.Value) : 0; + // Формируем заголовки и строки для таблицы + return new List { item } + .Union(markss.Select(g => new string[] + { + g.Date.ToString("dd.MM.yyyy"), + g.Subject, + g.Value.ToString(), + g.Teacher + })) + .Union(new[] + { + new string[] + { + "Средний балл", averageGrade.ToString("0.00"), "" + } + }) + .ToList(); + } +} \ No newline at end of file diff --git a/Academic_Performance/Academic_Performance/Reports/WordBuilder.cs b/Academic_Performance/Academic_Performance/Reports/WordBuilder.cs new file mode 100644 index 0000000..b9b033e --- /dev/null +++ b/Academic_Performance/Academic_Performance/Reports/WordBuilder.cs @@ -0,0 +1,94 @@ + +using DocumentFormat.OpenXml; +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Wordprocessing; +namespace Academic_Performance.Reports; + +public class WordBuilder +{ + private readonly string _filePath; + private readonly Document _document; + private readonly Body _body; + + public WordBuilder(string filePath) + { + if (string.IsNullOrWhiteSpace(filePath)) + { + throw new ArgumentNullException(nameof(filePath)); + } + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + _filePath = filePath; + _document = new Document(); + _body = _document.AppendChild(new Body()); + } + + public WordBuilder AddHeader(string header) + { + var paragraph = _body.AppendChild(new Paragraph()); + var run = paragraph.AppendChild(new Run()); + // TODO прописать настройки под жирный текст + run.PrependChild(new RunProperties()); + run.RunProperties.AddChild(new Bold()); + run.AppendChild(new Text(header)); + + return this; + } + + public WordBuilder AddParagraph(string text) + { + var paragraph = _body.AppendChild(new Paragraph()); + var run = paragraph.AppendChild(new Run()); + run.AppendChild(new Text(text)); + return this; + } + + public WordBuilder AddTable(int[] widths, List data) + { + if (widths == null || widths.Length == 0) + { + throw new ArgumentNullException(nameof(widths)); + } + if (data == null || data.Count == 0) + { + throw new ArgumentNullException(nameof(data)); + } + if (data.Any(x => x.Length != widths.Length)) + { + throw new InvalidOperationException("widths.Length != data.Length"); + } + var table = new Table(); + table.AppendChild(new TableProperties( + new TableBorders( + new TopBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new BottomBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new LeftBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new RightBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new InsideHorizontalBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new InsideVerticalBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }))); + + // Заголовок + var tr = new TableRow(); + for (var j = 0; j < widths.Length; ++j) + { + tr.Append(new TableCell(new TableCellProperties(new TableCellWidth() { Width = widths[j].ToString() }), + new Paragraph(new Run(new RunProperties(new Bold()), new Text(data.First()[j]))))); + } + table.Append(tr); + // Данные + table.Append(data.Skip(1).Select(x => new TableRow(x.Select(y => new TableCell(new Paragraph(new Run(new Text(y)))))))); + _body.Append(table); + return this; + } + + public void Build() + { + using var wordDocument = WordprocessingDocument.Create(_filePath, + WordprocessingDocumentType.Document); + var mainPart = wordDocument.AddMainDocumentPart(); + mainPart.Document = _document; + } +} + diff --git a/Academic_Performance/Academic_Performance/Repositories/IStatementRepository.cs b/Academic_Performance/Academic_Performance/Repositories/IStatementRepository.cs index 834e5b3..e098756 100644 --- a/Academic_Performance/Academic_Performance/Repositories/IStatementRepository.cs +++ b/Academic_Performance/Academic_Performance/Repositories/IStatementRepository.cs @@ -9,7 +9,7 @@ namespace Academic_Performance.Repositories { public interface IStatementRepository { - IEnumerable ReadStatement(DateTime? dateForm = null, DateTime? dateTo = null); + IEnumerable ReadStatement(DateTime? dateFrom = null, DateTime? dateTo = null); void CreateStatement(Statement statement); void DeleteStatement(int id); } diff --git a/Academic_Performance/Academic_Performance/Repositories/Implementations/StatementRepository.cs b/Academic_Performance/Academic_Performance/Repositories/Implementations/StatementRepository.cs index 5a9a9cd..ab43410 100644 --- a/Academic_Performance/Academic_Performance/Repositories/Implementations/StatementRepository.cs +++ b/Academic_Performance/Academic_Performance/Repositories/Implementations/StatementRepository.cs @@ -92,23 +92,42 @@ namespace Academic_Performance.Repositories.Implementations } } - public IEnumerable ReadStatement(DateTime? dateForm = null, DateTime? dateTo = null) + public IEnumerable ReadStatement(DateTime? dateFrom = null, DateTime? dateTo = null) { + _logger.LogInformation("Получение всех объектов"); try { using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var querySelect = "SELECT * FROM Statement11"; - var statements = connection.Query(querySelect); - _logger.LogDebug("Полученные объекты: {json}", - JsonConvert.SerializeObject(statements)); - return statements; + var querySelect = @"SELECT inv.*, ipr.StudentId, ipr.Value FROM Statement11 inv + INNER JOIN Markkk ipr ON ipr.Id = inv.Id"; + var statement = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(statement)); + return statement.GroupBy(x => x.Id, y => y, + (key, value) => Statement.CreateOperation(value.First(), + value.Select(z => Mark.CreateElement(0, z.StudentId, z.Value)))).ToList(); } catch (Exception ex) { _logger.LogError(ex, "Ошибка при чтении объектов"); throw; } + + + /// _logger.LogInformation("Получение всех объектов"); + /// try + /// { + /// using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + //// var statements = connection.Query(querySelect); + //// _logger.LogDebug("Полученные объекты: {json}", + /// JsonConvert.SerializeObject(statements)); + /// return statements; + /// } + /// catch (Exception ex) + /// { + /// _logger.LogError(ex, "Ошибка при чтении объектов"); + /// throw; + /// } } } } \ No newline at end of file