Compare commits

..

4 Commits

90 changed files with 7733 additions and 50 deletions

View File

@ -0,0 +1,34 @@
using ProjectSchedule.Entities.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace ProjectSchedule.Entities;
public class Audience
{
public int Id { get; private set; }
[DisplayName("Номер аудитории")]
public string Number { get; private set; } = string.Empty;
[DisplayName("Количество мест")]
public int SeatsCount { get; private set; }
[DisplayName("Тип аудитории")]
public TypeAudience TypeAudience { get; private set; }
public static Audience CreateEntity(int id, string number, TypeAudience typeAudience, int seatsCount)
{
return new Audience
{
Id = id,
Number = number ?? string.Empty,
TypeAudience = typeAudience,
SeatsCount = seatsCount
};
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace ProjectSchedule.Entities;
public class Discipline
{
public int Id { get; private set; }
[DisplayName("Название дисциплины")]
public string Name { get; private set; } = string.Empty;
public static Discipline CreateEntity(int id, string name)
{
return new Discipline
{
Id = id,
Name = name ?? string.Empty,
};
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Entities;
public class DisciplineStudingPlanSupplement
{
public int Id { get; private set; }
public int DisciplineId { get; private set; }
public string NameDiscipline { get; private set; } = string.Empty;
public int LecturesCount { get; private set; }
public int PracticesCount { get; private set; }
public static DisciplineStudingPlanSupplement CreateElement(int id, int disciplineId, int lecturesCount, int practicesCount)
{
return new DisciplineStudingPlanSupplement
{
Id = id,
DisciplineId = disciplineId,
LecturesCount = lecturesCount,
PracticesCount = practicesCount
};
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Entities.Enums;
[Flags]
public enum TypeAudience
{
None = 0,
СomputerСlass = 1,
LectureAudience = 2
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Entities.Enums;
public enum TypePair
{
None = 0,
Practice = 1,
Lecture = 2
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Entities.Enums;
public enum TypeWeek
{
None = 0,
OddWeek = 1,
EvenWeek = 2
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace ProjectSchedule.Entities;
public class Group
{
public int Id { get; private set; }
[DisplayName("Название группы")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Номер группы")]
public string GroupNumber { get; private set; } = string.Empty;
public string NameGroup => $"{Name}-{GroupNumber}";
[DisplayName("Количество студентов")]
public int StudentsCount { get; private set; }
public static Group CreateEntity(int id, string name, string groupNumber, int studentsCount)
{
return new Group
{
Id = id,
Name = name ?? string.Empty,
GroupNumber = groupNumber ?? string.Empty,
StudentsCount = studentsCount
};
}
}

View File

@ -0,0 +1,71 @@
using ProjectSchedule.Entities.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace ProjectSchedule.Entities;
public class Schedule
{
public int Id { get; private set; }
[Browsable(false)]
public int TeacherId { get; private set; }
[Browsable(false)]
public int DisciplineId { get; private set; }
[Browsable(false)]
public int GroupId { get; private set; }
[Browsable(false)]
public int AudienceId { get; private set; }
[DisplayName("Преподаватель")]
public string TeacherName { get; private set; } = string.Empty;
[DisplayName("Название дисциплины")]
public string NameDiscipline { get; private set; } = string.Empty;
[DisplayName("Группа студентов")]
public string NameGroup { get; private set; } = string.Empty;
[DisplayName("Номер аудитории")]
public string NumberAudience { get; private set; } = string.Empty;
[DisplayName("Дата дня")]
public DateTime DateDay { get; private set; }
[DisplayName("Номер дня")]
public int NumberDay { get; private set; }
[DisplayName("Номер пары")]
public int NumberPair { get; private set; }
[DisplayName("Номер недели")]
public TypeWeek TypeWeek { get; private set; }
[DisplayName("Тип пары")]
public TypePair TypePair { get; private set; }
public static Schedule CreateOperation(int id, int teacherId, int disciplineId, int groupId, int audienceId,
DateTime dateDay, TypeWeek typeWeek, int numberDay, int numberPair, TypePair typePair)
{
return new Schedule
{
Id = id,
TeacherId = teacherId,
DisciplineId = disciplineId,
GroupId = groupId,
AudienceId = audienceId,
DateDay = dateDay,
TypeWeek = typeWeek,
NumberDay = numberDay,
NumberPair = numberPair,
TypePair = typePair
};
}
}

View File

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace ProjectSchedule.Entities;
public class StudingPlanSupplement
{
public int Id { get; private set; }
[Browsable(false)]
public int GroupId { get; private set; }
[DisplayName("Группа студентов")]
public string NameGroup { get; private set; } = string.Empty;
[DisplayName("Название учебного плана")]
public string NameStudingPlan { get; private set; } = string.Empty;
[DisplayName("Семестр")]
public string Semester { get; private set; } = string.Empty;
[DisplayName("Дата принятия плана")]
public DateTime DateApprovePlan { get; private set; }
[DisplayName("Дисциплины")]
public string Discipline => DisciplineStudingPlanSupplements != null ?
string.Join(", ", DisciplineStudingPlanSupplements.Select(x => $"{x.NameDiscipline} {x.LecturesCount} {x.PracticesCount}")) : string.Empty;
[Browsable(false)]
public IEnumerable<DisciplineStudingPlanSupplement> DisciplineStudingPlanSupplements { get; private set; } = [];
public static StudingPlanSupplement CreateOperation(int id, int groupId, string nameStudingPlan,
string semester, DateTime dateApprovePlan, IEnumerable<DisciplineStudingPlanSupplement> disciplineStudingPlanSupplements)
{
return new StudingPlanSupplement
{
Id = id,
GroupId = groupId,
NameStudingPlan = nameStudingPlan ?? string.Empty,
Semester = semester ?? string.Empty,
DateApprovePlan = dateApprovePlan,
DisciplineStudingPlanSupplements = disciplineStudingPlanSupplements
};
}
public void SetDisciplineStudingPlanSupplements(IEnumerable<DisciplineStudingPlanSupplement> disciplineStudingPlanSupplements)
{
if (disciplineStudingPlanSupplements != null && disciplineStudingPlanSupplements.Any())
{
DisciplineStudingPlanSupplements = disciplineStudingPlanSupplements;
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace ProjectSchedule.Entities;
public class Teacher
{
public int Id { get; private set; }
[DisplayName("Фамилия")]
public string Surname { get; private set; } = string.Empty;
[DisplayName("Имя")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Отчество")]
public string Patronymic { get; private set; } = string.Empty;
public string FullName => $"{Surname} {Name} {Patronymic}";
public static Teacher CreateEntity(int id, string surname, string name, string patronymic)
{
return new Teacher
{
Id = id,
Surname = surname ?? string.Empty,
Name = name ?? string.Empty,
Patronymic = patronymic ?? string.Empty
};
}
}

View File

@ -1,39 +0,0 @@
namespace ProjectSchedule
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace ProjectSchedule
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,178 @@
namespace ProjectSchedule
{
partial class FormSchedule
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
menuStrip = new MenuStrip();
referencesToolStripMenuItem = new ToolStripMenuItem();
audiencesToolStripMenuItem = new ToolStripMenuItem();
disciplinesToolStripMenuItem = new ToolStripMenuItem();
teachersToolStripMenuItem = new ToolStripMenuItem();
groupsStudentsToolStripMenuItem = new ToolStripMenuItem();
operationsToolStripMenuItem = new ToolStripMenuItem();
scheduleToolStripMenuItem = new ToolStripMenuItem();
studingPlanSupplementToolStripMenuItem = new ToolStripMenuItem();
reportsToolStripMenuItem = new ToolStripMenuItem();
directoryReportToolStripMenuItem = new ToolStripMenuItem();
disciplineReportToolStripMenuItem = new ToolStripMenuItem();
distributionDisciplinesToolStripMenuItem = new ToolStripMenuItem();
menuStrip.SuspendLayout();
SuspendLayout();
//
// menuStrip
//
menuStrip.ImageScalingSize = new Size(20, 20);
menuStrip.Items.AddRange(new ToolStripItem[] { referencesToolStripMenuItem, operationsToolStripMenuItem, reportsToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(782, 28);
menuStrip.TabIndex = 0;
menuStrip.Text = "menuStrip";
//
// referencesToolStripMenuItem
//
referencesToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { audiencesToolStripMenuItem, disciplinesToolStripMenuItem, teachersToolStripMenuItem, groupsStudentsToolStripMenuItem });
referencesToolStripMenuItem.Name = "referencesToolStripMenuItem";
referencesToolStripMenuItem.Size = new Size(117, 24);
referencesToolStripMenuItem.Text = "Справочники";
//
// audiencesToolStripMenuItem
//
audiencesToolStripMenuItem.Name = "audiencesToolStripMenuItem";
audiencesToolStripMenuItem.Size = new Size(224, 26);
audiencesToolStripMenuItem.Text = "Аудитории";
audiencesToolStripMenuItem.Click += AudiencesToolStripMenuItem_Click;
//
// disciplinesToolStripMenuItem
//
disciplinesToolStripMenuItem.Name = "disciplinesToolStripMenuItem";
disciplinesToolStripMenuItem.Size = new Size(224, 26);
disciplinesToolStripMenuItem.Text = "Дисциплины";
disciplinesToolStripMenuItem.Click += DisciplinesToolStripMenuItem_Click;
//
// teachersToolStripMenuItem
//
teachersToolStripMenuItem.Name = "teachersToolStripMenuItem";
teachersToolStripMenuItem.Size = new Size(224, 26);
teachersToolStripMenuItem.Text = "Преподаватели";
teachersToolStripMenuItem.Click += TeachersToolStripMenuItem_Click;
//
// groupsStudentsToolStripMenuItem
//
groupsStudentsToolStripMenuItem.Name = "groupsStudentsToolStripMenuItem";
groupsStudentsToolStripMenuItem.Size = new Size(224, 26);
groupsStudentsToolStripMenuItem.Text = "Группы студентов";
groupsStudentsToolStripMenuItem.Click += GroupsToolStripMenuItem_Click;
//
// operationsToolStripMenuItem
//
operationsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { scheduleToolStripMenuItem, studingPlanSupplementToolStripMenuItem });
operationsToolStripMenuItem.Name = "operationsToolStripMenuItem";
operationsToolStripMenuItem.Size = new Size(95, 24);
operationsToolStripMenuItem.Text = "Операции";
//
// scheduleToolStripMenuItem
//
scheduleToolStripMenuItem.Name = "scheduleToolStripMenuItem";
scheduleToolStripMenuItem.Size = new Size(295, 26);
scheduleToolStripMenuItem.Text = "Составление расписания";
scheduleToolStripMenuItem.Click += ScheduleToolStripMenuItem_Click;
//
// studingPlanSupplementToolStripMenuItem
//
studingPlanSupplementToolStripMenuItem.Name = "studingPlanSupplementToolStripMenuItem";
studingPlanSupplementToolStripMenuItem.Size = new Size(295, 26);
studingPlanSupplementToolStripMenuItem.Text = "Дополнение учебного плана";
studingPlanSupplementToolStripMenuItem.Click += StudingPlanSupplementToolStripMenuItem_Click;
//
// reportsToolStripMenuItem
//
reportsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { directoryReportToolStripMenuItem, disciplineReportToolStripMenuItem, distributionDisciplinesToolStripMenuItem });
reportsToolStripMenuItem.Name = "reportsToolStripMenuItem";
reportsToolStripMenuItem.Size = new Size(73, 24);
reportsToolStripMenuItem.Text = "Отчёты";
//
// directoryReportToolStripMenuItem
//
directoryReportToolStripMenuItem.Name = "directoryReportToolStripMenuItem";
directoryReportToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.W;
directoryReportToolStripMenuItem.Size = new Size(350, 26);
directoryReportToolStripMenuItem.Text = "Документ со справочниками";
directoryReportToolStripMenuItem.Click += DirectoryReportToolStripMenuItem_Click;
//
// disciplineReportToolStripMenuItem
//
disciplineReportToolStripMenuItem.Name = "disciplineReportToolStripMenuItem";
disciplineReportToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.E;
disciplineReportToolStripMenuItem.Size = new Size(350, 26);
disciplineReportToolStripMenuItem.Text = "Прохождение дисциплин";
disciplineReportToolStripMenuItem.Click += DisciplineReportToolStripMenuItem_Click;
//
// distributionDisciplinesToolStripMenuItem
//
distributionDisciplinesToolStripMenuItem.Name = "distributionDisciplinesToolStripMenuItem";
distributionDisciplinesToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.P;
distributionDisciplinesToolStripMenuItem.Size = new Size(350, 26);
distributionDisciplinesToolStripMenuItem.Text = "Распределение дисциплин";
distributionDisciplinesToolStripMenuItem.Click += DistributionDisciplinesToolStripMenuItem_Click;
//
// FormSchedule
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
BackgroundImage = Properties.Resources.Bg;
BackgroundImageLayout = ImageLayout.Stretch;
ClientSize = new Size(782, 403);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormSchedule";
StartPosition = FormStartPosition.CenterScreen;
Text = "Расписание";
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private MenuStrip menuStrip;
private ToolStripMenuItem referencesToolStripMenuItem;
private ToolStripMenuItem audiencesToolStripMenuItem;
private ToolStripMenuItem disciplinesToolStripMenuItem;
private ToolStripMenuItem teachersToolStripMenuItem;
private ToolStripMenuItem groupsStudentsToolStripMenuItem;
private ToolStripMenuItem operationsToolStripMenuItem;
private ToolStripMenuItem scheduleToolStripMenuItem;
private ToolStripMenuItem reportsToolStripMenuItem;
private ToolStripMenuItem studingPlanSupplementToolStripMenuItem;
private ToolStripMenuItem directoryReportToolStripMenuItem;
private ToolStripMenuItem disciplineReportToolStripMenuItem;
private ToolStripMenuItem distributionDisciplinesToolStripMenuItem;
}
}

View File

@ -0,0 +1,125 @@
using ProjectSchedule.Forms;
using Unity;
namespace ProjectSchedule
{
public partial class FormSchedule : Form
{
private readonly IUnityContainer _container;
public FormSchedule(IUnityContainer container)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
}
private void AudiencesToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormAudiences>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DisciplinesToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormDisciplines>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void TeachersToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormTeachers>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void GroupsToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormGroups>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ScheduleToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormSchedules>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void StudingPlanSupplementToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormStudingPlanSupplements>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DirectoryReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormDirectoryReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DisciplineReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormDisciplineReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DistributionDisciplinesToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormDistributionDisciplinesReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,146 @@
namespace ProjectSchedule.Forms
{
partial class FormAudience
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelNumberAudience = new Label();
labelQuantitySeats = new Label();
labelTypeAudience = new Label();
buttonSave = new Button();
buttonCancel = new Button();
textBoxNumberAudience = new TextBox();
numericUpDownSeatsCount = new NumericUpDown();
checkedListBoxTypeAudience = new CheckedListBox();
((System.ComponentModel.ISupportInitialize)numericUpDownSeatsCount).BeginInit();
SuspendLayout();
//
// labelNumberAudience
//
labelNumberAudience.AutoSize = true;
labelNumberAudience.Location = new Point(21, 32);
labelNumberAudience.Name = "labelNumberAudience";
labelNumberAudience.Size = new Size(138, 20);
labelNumberAudience.TabIndex = 0;
labelNumberAudience.Text = "Номер аудитории:";
//
// labelQuantitySeats
//
labelQuantitySeats.AutoSize = true;
labelQuantitySeats.Location = new Point(21, 77);
labelQuantitySeats.Name = "labelQuantitySeats";
labelQuantitySeats.Size = new Size(129, 20);
labelQuantitySeats.TabIndex = 1;
labelQuantitySeats.Text = "Количество мест:";
//
// labelTypeAudience
//
labelTypeAudience.AutoSize = true;
labelTypeAudience.Location = new Point(21, 127);
labelTypeAudience.Name = "labelTypeAudience";
labelTypeAudience.Size = new Size(116, 20);
labelTypeAudience.TabIndex = 2;
labelTypeAudience.Text = "Тип аудитории:";
//
// buttonSave
//
buttonSave.Location = new Point(21, 300);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(116, 29);
buttonSave.TabIndex = 3;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(282, 300);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(116, 29);
buttonCancel.TabIndex = 4;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// textBoxNumberAudience
//
textBoxNumberAudience.Location = new Point(176, 29);
textBoxNumberAudience.Name = "textBoxNumberAudience";
textBoxNumberAudience.Size = new Size(222, 27);
textBoxNumberAudience.TabIndex = 5;
//
// numericUpDownQuantitySeats
//
numericUpDownSeatsCount.Location = new Point(176, 77);
numericUpDownSeatsCount.Maximum = new decimal(new int[] { 500, 0, 0, 0 });
numericUpDownSeatsCount.Minimum = new decimal(new int[] { 24, 0, 0, 0 });
numericUpDownSeatsCount.Name = "numericUpDownQuantitySeats";
numericUpDownSeatsCount.Size = new Size(222, 27);
numericUpDownSeatsCount.TabIndex = 6;
numericUpDownSeatsCount.Value = new decimal(new int[] { 24, 0, 0, 0 });
//
// checkedListBoxTypeAudience
//
checkedListBoxTypeAudience.FormattingEnabled = true;
checkedListBoxTypeAudience.Location = new Point(176, 127);
checkedListBoxTypeAudience.Name = "checkedListBoxTypeAudience";
checkedListBoxTypeAudience.Size = new Size(222, 136);
checkedListBoxTypeAudience.TabIndex = 7;
//
// FormAudience
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(412, 353);
Controls.Add(checkedListBoxTypeAudience);
Controls.Add(numericUpDownSeatsCount);
Controls.Add(textBoxNumberAudience);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(labelTypeAudience);
Controls.Add(labelQuantitySeats);
Controls.Add(labelNumberAudience);
Name = "FormAudience";
StartPosition = FormStartPosition.CenterParent;
Text = "Аудитория";
((System.ComponentModel.ISupportInitialize)numericUpDownSeatsCount).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelNumberAudience;
private Label labelQuantitySeats;
private Label labelTypeAudience;
private Button buttonSave;
private Button buttonCancel;
private TextBox textBoxNumberAudience;
private NumericUpDown numericUpDownSeatsCount;
private CheckedListBox checkedListBoxTypeAudience;
}
}

View File

@ -0,0 +1,95 @@
using ProjectSchedule.Entities.Enums;
using ProjectSchedule.Entities;
using ProjectSchedule.Repositories;
namespace ProjectSchedule.Forms;
public partial class FormAudience : Form
{
private readonly IAudienceRepository _audienceRepository;
private int? _audienceId;
public int Id
{
set
{
try
{
var audience = _audienceRepository.ReadAudienceById(value);
if (audience == null)
{
throw new InvalidDataException(nameof(audience));
}
foreach (TypeAudience elem in Enum.GetValues(typeof(TypeAudience)))
{
if ((elem & audience.TypeAudience) != 0)
{
checkedListBoxTypeAudience.SetItemChecked(checkedListBoxTypeAudience.Items.IndexOf(elem), true);
}
}
textBoxNumberAudience.Text = audience.Number;
numericUpDownSeatsCount.Value = audience.SeatsCount;
_audienceId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormAudience(IAudienceRepository audienceRepository)
{
InitializeComponent();
_audienceRepository = audienceRepository ??
throw new ArgumentNullException(nameof(audienceRepository));
foreach (var elem in Enum.GetValues(typeof(TypeAudience)))
{
checkedListBoxTypeAudience.Items.Add(elem);
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxNumberAudience.Text) || checkedListBoxTypeAudience.CheckedItems.Count == 0)
{
throw new Exception("Имеются незаполненные поля");
}
if (_audienceId.HasValue)
{
_audienceRepository.UpdateAudience(CreateAudience(_audienceId.Value));
}
else
{
_audienceRepository.CreateAudience(CreateAudience(0));
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private Audience CreateAudience(int id)
{
TypeAudience typeAudience = TypeAudience.None;
foreach (var elem in checkedListBoxTypeAudience.CheckedItems)
{
typeAudience |= (TypeAudience)elem;
}
return Audience.CreateEntity(id, textBoxNumberAudience.Text, typeAudience, Convert.ToInt32(numericUpDownSeatsCount.Value));
}
}

View File

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

View File

@ -0,0 +1,127 @@
namespace ProjectSchedule.Forms
{
partial class FormAudiences
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
panelButtons = new Panel();
buttonDel = new Button();
buttonUpd = new Button();
buttonAdd = new Button();
dataGridViewData = new DataGridView();
panelButtons.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
SuspendLayout();
//
// panelButtons
//
panelButtons.Controls.Add(buttonDel);
panelButtons.Controls.Add(buttonUpd);
panelButtons.Controls.Add(buttonAdd);
panelButtons.Dock = DockStyle.Right;
panelButtons.Location = new Point(672, 0);
panelButtons.Name = "panelButtons";
panelButtons.Size = new Size(140, 483);
panelButtons.TabIndex = 0;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.Del;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(24, 194);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(94, 66);
buttonDel.TabIndex = 4;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonUpd
//
buttonUpd.BackgroundImage = Properties.Resources.Upd;
buttonUpd.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpd.Location = new Point(24, 106);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(94, 66);
buttonUpd.TabIndex = 3;
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.Add;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(24, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(94, 66);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.RowHeadersWidth = 51;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(672, 483);
dataGridViewData.TabIndex = 1;
//
// FormAudiences
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(812, 483);
Controls.Add(dataGridViewData);
Controls.Add(panelButtons);
Name = "FormAudiences";
StartPosition = FormStartPosition.CenterParent;
Text = "Аудитории";
Load += FormAudiences_Load;
panelButtons.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
ResumeLayout(false);
}
#endregion
private Panel panelButtons;
private Button buttonDel;
private Button buttonUpd;
private Button buttonAdd;
private DataGridView dataGridViewData;
}
}

View File

@ -0,0 +1,108 @@
using ProjectSchedule.Repositories;
using Unity;
namespace ProjectSchedule.Forms
{
public partial class FormAudiences : Form
{
private readonly IUnityContainer _container;
private readonly IAudienceRepository _audienceRepository;
public FormAudiences(IUnityContainer container, IAudienceRepository audienceRepository)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
_audienceRepository = audienceRepository ??
throw new ArgumentNullException(nameof(audienceRepository));
}
private void FormAudiences_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormAudience>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FormAudience>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_audienceRepository.DeleteAudience(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _audienceRepository.ReadAudiences();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewData.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewData.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

View File

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

View File

@ -0,0 +1,113 @@
namespace ProjectSchedule.Forms
{
partial class FormDirectoryReport
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
checkBoxAudiences = new CheckBox();
checkBoxDisciplines = new CheckBox();
checkBoxTeachers = new CheckBox();
checkBoxGroupsStudents = new CheckBox();
buttonBuild = new Button();
SuspendLayout();
//
// checkBoxAudiences
//
checkBoxAudiences.AutoSize = true;
checkBoxAudiences.Location = new Point(27, 12);
checkBoxAudiences.Name = "checkBoxAudiences";
checkBoxAudiences.Size = new Size(107, 24);
checkBoxAudiences.TabIndex = 0;
checkBoxAudiences.Text = "Аудитории";
checkBoxAudiences.UseVisualStyleBackColor = true;
//
// checkBoxDisciplines
//
checkBoxDisciplines.AutoSize = true;
checkBoxDisciplines.Location = new Point(27, 42);
checkBoxDisciplines.Name = "checkBoxDisciplines";
checkBoxDisciplines.Size = new Size(121, 24);
checkBoxDisciplines.TabIndex = 1;
checkBoxDisciplines.Text = "Дисциплины";
checkBoxDisciplines.UseVisualStyleBackColor = true;
//
// checkBoxEducators
//
checkBoxTeachers.AutoSize = true;
checkBoxTeachers.Location = new Point(27, 72);
checkBoxTeachers.Name = "checkBoxEducators";
checkBoxTeachers.Size = new Size(140, 24);
checkBoxTeachers.TabIndex = 2;
checkBoxTeachers.Text = "Преподаватели";
checkBoxTeachers.UseVisualStyleBackColor = true;
//
// checkBoxGroupsStudents
//
checkBoxGroupsStudents.AutoSize = true;
checkBoxGroupsStudents.Location = new Point(27, 102);
checkBoxGroupsStudents.Name = "checkBoxGroupsStudents";
checkBoxGroupsStudents.Size = new Size(155, 24);
checkBoxGroupsStudents.TabIndex = 3;
checkBoxGroupsStudents.Text = "Группы студентов";
checkBoxGroupsStudents.UseVisualStyleBackColor = true;
//
// buttonBuild
//
buttonBuild.Location = new Point(209, 53);
buttonBuild.Name = "buttonBuild";
buttonBuild.Size = new Size(126, 29);
buttonBuild.TabIndex = 4;
buttonBuild.Text = "Сформировать";
buttonBuild.UseVisualStyleBackColor = true;
buttonBuild.Click += ButtonBuild_Click;
//
// FormDirectoryReport
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(372, 138);
Controls.Add(buttonBuild);
Controls.Add(checkBoxGroupsStudents);
Controls.Add(checkBoxTeachers);
Controls.Add(checkBoxDisciplines);
Controls.Add(checkBoxAudiences);
Name = "FormDirectoryReport";
StartPosition = FormStartPosition.CenterParent;
Text = "Выгрузка справочников";
ResumeLayout(false);
PerformLayout();
}
#endregion
private CheckBox checkBoxAudiences;
private CheckBox checkBoxDisciplines;
private CheckBox checkBoxTeachers;
private CheckBox checkBoxGroupsStudents;
private Button buttonBuild;
}
}

View File

@ -0,0 +1,55 @@
using ProjectSchedule.Reports;
using Unity;
namespace ProjectSchedule.Forms
{
public partial class FormDirectoryReport : Form
{
private readonly IUnityContainer _container;
public FormDirectoryReport(IUnityContainer container)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
}
private void ButtonBuild_Click(object sender, EventArgs e)
{
try
{
if (!checkBoxAudiences.Checked && !checkBoxDisciplines.Checked
&& !checkBoxTeachers.Checked && !checkBoxGroupsStudents.Checked)
{
throw new Exception("Не выбран ни один справочник для выгрузки");
}
var sfd = new SaveFileDialog()
{
Filter = "Docx Files | *.docx"
};
if (sfd.ShowDialog() != DialogResult.OK)
{
throw new Exception("Не выбран файла для отчета");
}
if (_container.Resolve<DocReport>().CreateDoc(sfd.FileName, checkBoxAudiences.Checked,
checkBoxDisciplines.Checked, checkBoxTeachers.Checked, checkBoxGroupsStudents.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);
}
}
}
}

View File

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

View File

@ -0,0 +1,96 @@
namespace ProjectSchedule.Forms
{
partial class FormDiscipline
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
textBoxNameDiscipline = new TextBox();
labelNameDiscipline = new Label();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// textBoxNameDiscipline
//
textBoxNameDiscipline.Location = new Point(228, 42);
textBoxNameDiscipline.Name = "textBoxNameDiscipline";
textBoxNameDiscipline.Size = new Size(214, 27);
textBoxNameDiscipline.TabIndex = 0;
//
// labelNameDiscipline
//
labelNameDiscipline.AutoSize = true;
labelNameDiscipline.Location = new Point(25, 45);
labelNameDiscipline.Name = "labelNameDiscipline";
labelNameDiscipline.Size = new Size(172, 20);
labelNameDiscipline.TabIndex = 1;
labelNameDiscipline.Text = "Название дисциплины:";
//
// buttonSave
//
buttonSave.Location = new Point(25, 131);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(116, 29);
buttonSave.TabIndex = 4;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(326, 131);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(116, 29);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormDiscipline
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(468, 184);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(labelNameDiscipline);
Controls.Add(textBoxNameDiscipline);
Name = "FormDiscipline";
StartPosition = FormStartPosition.CenterParent;
Text = "Дисциплина";
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxNameDiscipline;
private Label labelNameDiscipline;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,72 @@
using ProjectSchedule.Entities;
using ProjectSchedule.Repositories;
namespace ProjectSchedule.Forms;
public partial class FormDiscipline : Form
{
private readonly IDisciplineRepository _disciplineRepository;
private int? _disciplineId;
public int Id
{
set
{
try
{
var discipline = _disciplineRepository.ReadDisciplineById(value);
if (discipline == null)
{
throw new InvalidDataException(nameof(discipline));
}
textBoxNameDiscipline.Text = discipline.Name;
_disciplineId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormDiscipline(IDisciplineRepository disciplineRepository)
{
InitializeComponent();
_disciplineRepository = disciplineRepository ??
throw new ArgumentNullException(nameof(disciplineRepository));
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxNameDiscipline.Text))
{
throw new Exception("Поле 'Название дисциплины' должно быть заполнено.");
}
if (_disciplineId.HasValue)
{
_disciplineRepository.UpdateDiscipline(CreateDiscipline(_disciplineId.Value));
}
else
{
_disciplineRepository.CreateDiscipline(CreateDiscipline(0));
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private Discipline CreateDiscipline(int id) =>
Discipline.CreateEntity(id, textBoxNameDiscipline.Text);
}

View File

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

View File

@ -0,0 +1,165 @@
namespace ProjectSchedule.Forms
{
partial class FormDisciplineReport
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dateTimePickerDateBegin = new DateTimePicker();
dateTimePickerDateEnd = new DateTimePicker();
textBoxFilePath = new TextBox();
buttonSelectFilePath = new Button();
labelPathFile = new Label();
labelDateBegin = new Label();
labelDateEnd = new Label();
labelDiscipline = new Label();
comboBoxDiscipline = new ComboBox();
buttonMakeReport = new Button();
SuspendLayout();
//
// dateTimePickerDateBegin
//
dateTimePickerDateBegin.Location = new Point(155, 109);
dateTimePickerDateBegin.Name = "dateTimePickerDateBegin";
dateTimePickerDateBegin.Size = new Size(250, 27);
dateTimePickerDateBegin.TabIndex = 0;
//
// dateTimePickerDateEnd
//
dateTimePickerDateEnd.Location = new Point(155, 147);
dateTimePickerDateEnd.Name = "dateTimePickerDateEnd";
dateTimePickerDateEnd.Size = new Size(250, 27);
dateTimePickerDateEnd.TabIndex = 1;
//
// textBoxFilePath
//
textBoxFilePath.Location = new Point(155, 29);
textBoxFilePath.Name = "textBoxFilePath";
textBoxFilePath.ReadOnly = true;
textBoxFilePath.Size = new Size(192, 27);
textBoxFilePath.TabIndex = 2;
//
// buttonSelectFilePath
//
buttonSelectFilePath.Location = new Point(353, 29);
buttonSelectFilePath.Name = "buttonSelectFilePath";
buttonSelectFilePath.Size = new Size(52, 29);
buttonSelectFilePath.TabIndex = 4;
buttonSelectFilePath.Text = "..";
buttonSelectFilePath.UseVisualStyleBackColor = true;
buttonSelectFilePath.Click += ButtonSelectFilePath_Click;
//
// labelPathFile
//
labelPathFile.AutoSize = true;
labelPathFile.Location = new Point(31, 32);
labelPathFile.Name = "labelPathFile";
labelPathFile.Size = new Size(112, 20);
labelPathFile.TabIndex = 6;
labelPathFile.Text = "Путь до файла:";
//
// labelDateBegin
//
labelDateBegin.AutoSize = true;
labelDateBegin.Location = new Point(31, 114);
labelDateBegin.Name = "labelDateBegin";
labelDateBegin.Size = new Size(97, 20);
labelDateBegin.TabIndex = 7;
labelDateBegin.Text = "Дата начала:";
//
// labelDateEnd
//
labelDateEnd.AutoSize = true;
labelDateEnd.Location = new Point(31, 152);
labelDateEnd.Name = "labelDateEnd";
labelDateEnd.Size = new Size(90, 20);
labelDateEnd.TabIndex = 8;
labelDateEnd.Text = "Дата конца:";
//
// labelDiscipline
//
labelDiscipline.AutoSize = true;
labelDiscipline.Location = new Point(31, 73);
labelDiscipline.Name = "labelDiscipline";
labelDiscipline.Size = new Size(99, 20);
labelDiscipline.TabIndex = 9;
labelDiscipline.Text = "Дисциплина:";
//
// comboBoxDiscipline
//
comboBoxDiscipline.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxDiscipline.FormattingEnabled = true;
comboBoxDiscipline.Location = new Point(155, 70);
comboBoxDiscipline.Name = "comboBoxDiscipline";
comboBoxDiscipline.Size = new Size(250, 28);
comboBoxDiscipline.TabIndex = 10;
//
// buttonMakeReport
//
buttonMakeReport.Location = new Point(107, 201);
buttonMakeReport.Name = "buttonMakeReport";
buttonMakeReport.Size = new Size(208, 29);
buttonMakeReport.TabIndex = 11;
buttonMakeReport.Text = "Сформировать";
buttonMakeReport.UseVisualStyleBackColor = true;
buttonMakeReport.Click += ButtonMakeReport_Click;
//
// FormDisciplineReport
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(432, 242);
Controls.Add(buttonMakeReport);
Controls.Add(comboBoxDiscipline);
Controls.Add(labelDiscipline);
Controls.Add(labelDateEnd);
Controls.Add(labelDateBegin);
Controls.Add(labelPathFile);
Controls.Add(buttonSelectFilePath);
Controls.Add(textBoxFilePath);
Controls.Add(dateTimePickerDateEnd);
Controls.Add(dateTimePickerDateBegin);
Name = "FormDisciplineReport";
StartPosition = FormStartPosition.CenterParent;
Text = "Отчёт по дисциплине";
ResumeLayout(false);
PerformLayout();
}
#endregion
private DateTimePicker dateTimePickerDateBegin;
private DateTimePicker dateTimePickerDateEnd;
private TextBox textBoxFilePath;
private Button buttonSelectFilePath;
private Label labelPathFile;
private Label labelDateBegin;
private Label labelDateEnd;
private Label labelDiscipline;
private ComboBox comboBoxDiscipline;
private Button buttonMakeReport;
}
}

View File

@ -0,0 +1,74 @@
using ProjectSchedule.Reports;
using ProjectSchedule.Repositories;
using Unity;
namespace ProjectSchedule.Forms
{
public partial class FormDisciplineReport : Form
{
private readonly IUnityContainer _container;
public FormDisciplineReport(IUnityContainer container, IDisciplineRepository disciplineRepository)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
comboBoxDiscipline.DataSource = disciplineRepository.ReadDisciplines();
comboBoxDiscipline.DisplayMember = "Name";
comboBoxDiscipline.ValueMember = "Id";
}
private void ButtonSelectFilePath_Click(object sender, EventArgs e)
{
var sfd = new SaveFileDialog()
{
Filter = "Excel Files | *.xlsx"
};
if (sfd.ShowDialog() != DialogResult.OK)
{
return;
}
textBoxFilePath.Text = sfd.FileName;
}
private void ButtonMakeReport_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxFilePath.Text))
{
throw new Exception("Отсутствует имя файла для отчета");
}
if (comboBoxDiscipline.SelectedIndex < 0)
{
throw new Exception("Не выбрана дисциплина");
}
if (dateTimePickerDateEnd.Value <= dateTimePickerDateBegin.Value)
{
throw new Exception("Дата начала должна быть раньше даты окончания");
}
if (_container.Resolve<TableReport>().CreateTable(textBoxFilePath.Text,
(int)comboBoxDiscipline.SelectedValue!, dateTimePickerDateBegin.Value, dateTimePickerDateEnd.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);
}
}
}
}

View File

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

View File

@ -0,0 +1,127 @@
namespace ProjectSchedule.Forms
{
partial class FormDisciplines
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
panelButtons = new Panel();
buttonDel = new Button();
buttonUpd = new Button();
buttonAdd = new Button();
dataGridViewData = new DataGridView();
panelButtons.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
SuspendLayout();
//
// panelButtons
//
panelButtons.Controls.Add(buttonDel);
panelButtons.Controls.Add(buttonUpd);
panelButtons.Controls.Add(buttonAdd);
panelButtons.Dock = DockStyle.Right;
panelButtons.Location = new Point(660, 0);
panelButtons.Name = "panelButtons";
panelButtons.Size = new Size(140, 450);
panelButtons.TabIndex = 1;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.Del;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(24, 194);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(94, 66);
buttonDel.TabIndex = 4;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonUpd
//
buttonUpd.BackgroundImage = Properties.Resources.Upd;
buttonUpd.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpd.Location = new Point(24, 106);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(94, 66);
buttonUpd.TabIndex = 3;
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.Add;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(24, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(94, 66);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.RowHeadersWidth = 51;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(660, 450);
dataGridViewData.TabIndex = 2;
//
// FormDisciplines
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridViewData);
Controls.Add(panelButtons);
Name = "FormDisciplines";
StartPosition = FormStartPosition.CenterParent;
Text = "Дисциплины";
Load += FormDisciplines_Load;
panelButtons.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
ResumeLayout(false);
}
#endregion
private Panel panelButtons;
private Button buttonDel;
private Button buttonUpd;
private Button buttonAdd;
private DataGridView dataGridViewData;
}
}

View File

@ -0,0 +1,108 @@
using ProjectSchedule.Repositories;
using Unity;
namespace ProjectSchedule.Forms
{
public partial class FormDisciplines : Form
{
private readonly IUnityContainer _container;
private readonly IDisciplineRepository _disciplineRepository;
public FormDisciplines(IUnityContainer container, IDisciplineRepository disciplineRepository)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
_disciplineRepository = disciplineRepository ??
throw new ArgumentNullException(nameof(disciplineRepository));
}
private void FormDisciplines_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormDiscipline>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FormDiscipline>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_disciplineRepository.DeleteDiscipline(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _disciplineRepository.ReadDisciplines();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewData.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewData.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

View File

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

View File

@ -0,0 +1,108 @@
namespace ProjectSchedule.Forms
{
partial class FormDistributionDisciplinesReport
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelFileName = new Label();
dateTimePicker = new DateTimePicker();
labelDate = new Label();
buttonSelectFileName = new Button();
buttonCreate = new Button();
SuspendLayout();
//
// labelFileName
//
labelFileName.AutoSize = true;
labelFileName.Location = new Point(173, 36);
labelFileName.Name = "labelFileName";
labelFileName.Size = new Size(45, 20);
labelFileName.TabIndex = 0;
labelFileName.Text = "Файл";
//
// dateTimePicker
//
dateTimePicker.Location = new Point(173, 99);
dateTimePicker.Name = "dateTimePicker";
dateTimePicker.Size = new Size(229, 27);
dateTimePicker.TabIndex = 1;
//
// labelDate
//
labelDate.AutoSize = true;
labelDate.Location = new Point(30, 104);
labelDate.Name = "labelDate";
labelDate.Size = new Size(44, 20);
labelDate.TabIndex = 2;
labelDate.Text = "Дата:";
//
// buttonSelectFileName
//
buttonSelectFileName.Location = new Point(30, 32);
buttonSelectFileName.Name = "buttonSelectFileName";
buttonSelectFileName.Size = new Size(94, 29);
buttonSelectFileName.TabIndex = 3;
buttonSelectFileName.Text = "Выбрать";
buttonSelectFileName.UseVisualStyleBackColor = true;
buttonSelectFileName.Click += ButtonSelectFileName_Click;
//
// buttonCreate
//
buttonCreate.Location = new Point(156, 167);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(126, 29);
buttonCreate.TabIndex = 5;
buttonCreate.Text = "Сформировать";
buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += ButtonCreate_Click;
//
// FormDistributionDisciplinesReport
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(433, 208);
Controls.Add(buttonCreate);
Controls.Add(buttonSelectFileName);
Controls.Add(labelDate);
Controls.Add(dateTimePicker);
Controls.Add(labelFileName);
Name = "FormDistributionDisciplinesReport";
StartPosition = FormStartPosition.CenterParent;
Text = "Распределение дисциплин";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelFileName;
private DateTimePicker dateTimePicker;
private Label labelDate;
private Button buttonSelectFileName;
private Button buttonCreate;
}
}

View File

@ -0,0 +1,59 @@
using ProjectSchedule.Reports;
using Unity;
namespace ProjectSchedule.Forms
{
public partial class FormDistributionDisciplinesReport : Form
{
private string _fileName = string.Empty;
private readonly IUnityContainer _container;
public FormDistributionDisciplinesReport(IUnityContainer container)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
}
private void ButtonSelectFileName_Click(object sender, EventArgs e)
{
var sfd = new SaveFileDialog()
{
Filter = "Pdf Files | *.pdf"
};
if (sfd.ShowDialog() == DialogResult.OK)
{
_fileName = sfd.FileName;
labelFileName.Text = Path.GetFileName(_fileName);
}
}
private void ButtonCreate_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(_fileName))
{
throw new Exception("Отсутствует имя файла для отчета");
}
if (_container.Resolve<ChartReport>().CreateChart(_fileName, dateTimePicker.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);
}
}
}
}

View File

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

View File

@ -0,0 +1,145 @@
namespace ProjectSchedule.Forms
{
partial class FormGroup
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelAbbreviationGroup = new Label();
labelGroupNumber = new Label();
labelQuantityStudents = new Label();
numericUpDownStudentsCount = new NumericUpDown();
textBoxNameGroup = new TextBox();
textBoxGroupNumber = new TextBox();
buttonSave = new Button();
buttonCancel = new Button();
((System.ComponentModel.ISupportInitialize)numericUpDownStudentsCount).BeginInit();
SuspendLayout();
//
// labelAbbreviationGroup
//
labelAbbreviationGroup.AutoSize = true;
labelAbbreviationGroup.Location = new Point(12, 28);
labelAbbreviationGroup.Name = "labelAbbreviationGroup";
labelAbbreviationGroup.Size = new Size(167, 20);
labelAbbreviationGroup.TabIndex = 0;
labelAbbreviationGroup.Text = "Аббревиатура группы:";
//
// labelGroupNumber
//
labelGroupNumber.AutoSize = true;
labelGroupNumber.Location = new Point(12, 74);
labelGroupNumber.Name = "labelGroupNumber";
labelGroupNumber.Size = new Size(115, 20);
labelGroupNumber.TabIndex = 1;
labelGroupNumber.Text = "Номер группы:";
//
// labelQuantityStudents
//
labelQuantityStudents.AutoSize = true;
labelQuantityStudents.Location = new Point(12, 123);
labelQuantityStudents.Name = "labelQuantityStudents";
labelQuantityStudents.Size = new Size(165, 20);
labelQuantityStudents.TabIndex = 2;
labelQuantityStudents.Text = "Количество студентов:";
//
// numericUpDownQuantityStudents
//
numericUpDownStudentsCount.Location = new Point(213, 121);
numericUpDownStudentsCount.Maximum = new decimal(new int[] { 66, 0, 0, 0 });
numericUpDownStudentsCount.Minimum = new decimal(new int[] { 2, 0, 0, 0 });
numericUpDownStudentsCount.Name = "numericUpDownQuantityStudents";
numericUpDownStudentsCount.Size = new Size(176, 27);
numericUpDownStudentsCount.TabIndex = 3;
numericUpDownStudentsCount.Value = new decimal(new int[] { 2, 0, 0, 0 });
//
// textBoxAbbreviationGroup
//
textBoxNameGroup.Location = new Point(213, 25);
textBoxNameGroup.Name = "textBoxAbbreviationGroup";
textBoxNameGroup.Size = new Size(176, 27);
textBoxNameGroup.TabIndex = 4;
//
// textBoxGroupNumber
//
textBoxGroupNumber.Location = new Point(213, 71);
textBoxGroupNumber.Name = "textBoxGroupNumber";
textBoxGroupNumber.Size = new Size(176, 27);
textBoxGroupNumber.TabIndex = 5;
//
// buttonSave
//
buttonSave.Location = new Point(12, 189);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(116, 29);
buttonSave.TabIndex = 7;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(273, 189);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(116, 29);
buttonCancel.TabIndex = 8;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormGroupStudents
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(401, 230);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxGroupNumber);
Controls.Add(textBoxNameGroup);
Controls.Add(numericUpDownStudentsCount);
Controls.Add(labelQuantityStudents);
Controls.Add(labelGroupNumber);
Controls.Add(labelAbbreviationGroup);
Name = "FormGroupStudents";
StartPosition = FormStartPosition.CenterParent;
Text = "Группа студентов";
((System.ComponentModel.ISupportInitialize)numericUpDownStudentsCount).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelAbbreviationGroup;
private Label labelGroupNumber;
private Label labelQuantityStudents;
private NumericUpDown numericUpDownStudentsCount;
private TextBox textBoxNameGroup;
private TextBox textBoxGroupNumber;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,74 @@
using ProjectSchedule.Entities;
using ProjectSchedule.Repositories;
namespace ProjectSchedule.Forms;
public partial class FormGroup : Form
{
private readonly IGroupRepository _groupRepository;
private int? _groupId;
public int Id
{
set
{
try
{
var group = _groupRepository.ReadGroupById(value);
if (group == null)
{
throw new InvalidDataException(nameof(group));
}
textBoxNameGroup.Text = group.Name;
textBoxGroupNumber.Text = group.GroupNumber;
numericUpDownStudentsCount.Value = group.StudentsCount;
_groupId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormGroup(IGroupRepository groupRepository)
{
InitializeComponent();
_groupRepository = groupRepository ??
throw new ArgumentNullException(nameof(groupRepository));
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxNameGroup.Text) || string.IsNullOrWhiteSpace(textBoxGroupNumber.Text))
{
throw new Exception("Имеются незаполненные поля");
}
if (_groupId.HasValue)
{
_groupRepository.UpdateGroup(CreateGroup(_groupId.Value));
}
else
{
_groupRepository.CreateGroup(CreateGroup(0));
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private Group CreateGroup(int id) =>
Group.CreateEntity(id, textBoxNameGroup.Text, textBoxGroupNumber.Text, Convert.ToInt32(numericUpDownStudentsCount.Value));
}

View File

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

View File

@ -0,0 +1,127 @@
namespace ProjectSchedule.Forms
{
partial class FormGroups
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
panelButtons = new Panel();
buttonDel = new Button();
buttonUpd = new Button();
buttonAdd = new Button();
dataGridViewData = new DataGridView();
panelButtons.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
SuspendLayout();
//
// panelButtons
//
panelButtons.Controls.Add(buttonDel);
panelButtons.Controls.Add(buttonUpd);
panelButtons.Controls.Add(buttonAdd);
panelButtons.Dock = DockStyle.Right;
panelButtons.Location = new Point(660, 0);
panelButtons.Name = "panelButtons";
panelButtons.Size = new Size(140, 450);
panelButtons.TabIndex = 2;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.Del;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(24, 194);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(94, 66);
buttonDel.TabIndex = 4;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonUpd
//
buttonUpd.BackgroundImage = Properties.Resources.Upd;
buttonUpd.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpd.Location = new Point(24, 106);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(94, 66);
buttonUpd.TabIndex = 3;
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.Add;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(24, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(94, 66);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.RowHeadersWidth = 51;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(660, 450);
dataGridViewData.TabIndex = 3;
//
// FormGroupsStudents
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridViewData);
Controls.Add(panelButtons);
Name = "FormGroupsStudents";
StartPosition = FormStartPosition.CenterParent;
Text = "Группы студентов";
Load += FormGroups_Load;
panelButtons.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
ResumeLayout(false);
}
#endregion
private Panel panelButtons;
private Button buttonDel;
private Button buttonUpd;
private Button buttonAdd;
private DataGridView dataGridViewData;
}
}

View File

@ -0,0 +1,109 @@
using ProjectSchedule.Repositories;
using Unity;
namespace ProjectSchedule.Forms
{
public partial class FormGroups : Form
{
private readonly IUnityContainer _container;
private readonly IGroupRepository _groupRepository;
public FormGroups(IUnityContainer container, IGroupRepository groupRepository)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
_groupRepository = groupRepository ??
throw new ArgumentNullException(nameof(groupRepository));
}
private void FormGroups_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormGroup>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FormGroup>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_groupRepository.DeleteGroup(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _groupRepository.ReadGroups();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["NameGroup"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewData.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewData.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

View File

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

View File

@ -0,0 +1,294 @@
namespace ProjectSchedule.Forms
{
partial class FormSchedule
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelEducator = new Label();
labelDiscipline = new Label();
labelAudience = new Label();
labelGroupStudents = new Label();
labelNumberDay = new Label();
labelTypeWeek = new Label();
labelNumberPair = new Label();
labelTypeActivity = new Label();
comboBoxDiscipline = new ComboBox();
comboBoxGroup = new ComboBox();
comboBoxTeacher = new ComboBox();
comboBoxAudience = new ComboBox();
comboBoxTypeWeek = new ComboBox();
comboBoxTypePair = new ComboBox();
numericUpDownNumberPair = new NumericUpDown();
numericUpDownNumberDay = new NumericUpDown();
buttonSave = new Button();
buttonCancel = new Button();
labelDateDay = new Label();
dateTimePickerDateDay = new DateTimePicker();
((System.ComponentModel.ISupportInitialize)numericUpDownNumberPair).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownNumberDay).BeginInit();
SuspendLayout();
//
// labelEducator
//
labelEducator.AutoSize = true;
labelEducator.Location = new Point(34, 27);
labelEducator.Name = "labelEducator";
labelEducator.Size = new Size(120, 20);
labelEducator.TabIndex = 0;
labelEducator.Text = "Преподаватель:";
//
// labelDiscipline
//
labelDiscipline.AutoSize = true;
labelDiscipline.Location = new Point(34, 66);
labelDiscipline.Name = "labelDiscipline";
labelDiscipline.Size = new Size(99, 20);
labelDiscipline.TabIndex = 1;
labelDiscipline.Text = "Дисциплина:";
//
// labelAudience
//
labelAudience.AutoSize = true;
labelAudience.Location = new Point(34, 159);
labelAudience.Name = "labelAudience";
labelAudience.Size = new Size(87, 20);
labelAudience.TabIndex = 2;
labelAudience.Text = "Аудитория:";
//
// labelGroupStudents
//
labelGroupStudents.AutoSize = true;
labelGroupStudents.Location = new Point(34, 111);
labelGroupStudents.Name = "labelGroupStudents";
labelGroupStudents.Size = new Size(133, 20);
labelGroupStudents.TabIndex = 3;
labelGroupStudents.Text = "Группа студентов:";
//
// labelNumberDay
//
labelNumberDay.AutoSize = true;
labelNumberDay.Location = new Point(34, 285);
labelNumberDay.Name = "labelNumberDay";
labelNumberDay.Size = new Size(89, 20);
labelNumberDay.TabIndex = 4;
labelNumberDay.Text = "Номер дня:";
//
// labelTypeWeek
//
labelTypeWeek.AutoSize = true;
labelTypeWeek.Location = new Point(34, 207);
labelTypeWeek.Name = "labelTypeWeek";
labelTypeWeek.Size = new Size(63, 20);
labelTypeWeek.TabIndex = 5;
labelTypeWeek.Text = "Неделя:";
//
// labelNumberPair
//
labelNumberPair.AutoSize = true;
labelNumberPair.Location = new Point(32, 331);
labelNumberPair.Name = "labelNumberPair";
labelNumberPair.Size = new Size(101, 20);
labelNumberPair.TabIndex = 6;
labelNumberPair.Text = "Номер пары:";
//
// labelTypeActivity
//
labelTypeActivity.AutoSize = true;
labelTypeActivity.Location = new Point(34, 375);
labelTypeActivity.Name = "labelTypeActivity";
labelTypeActivity.Size = new Size(97, 20);
labelTypeActivity.TabIndex = 7;
labelTypeActivity.Text = "Тип занятия:";
//
// comboBoxDiscipline
//
comboBoxDiscipline.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxDiscipline.FormattingEnabled = true;
comboBoxDiscipline.Location = new Point(245, 66);
comboBoxDiscipline.Name = "comboBoxDiscipline";
comboBoxDiscipline.Size = new Size(210, 28);
comboBoxDiscipline.TabIndex = 8;
//
// comboBoxGroupStudents
//
comboBoxGroup.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxGroup.FormattingEnabled = true;
comboBoxGroup.Location = new Point(245, 108);
comboBoxGroup.Name = "comboBoxGroupStudents";
comboBoxGroup.Size = new Size(210, 28);
comboBoxGroup.TabIndex = 9;
//
// comboBoxEducator
//
comboBoxTeacher.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxTeacher.FormattingEnabled = true;
comboBoxTeacher.Location = new Point(245, 24);
comboBoxTeacher.Name = "comboBoxEducator";
comboBoxTeacher.Size = new Size(210, 28);
comboBoxTeacher.TabIndex = 10;
//
// comboBoxAudience
//
comboBoxAudience.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxAudience.FormattingEnabled = true;
comboBoxAudience.Location = new Point(245, 159);
comboBoxAudience.Name = "comboBoxAudience";
comboBoxAudience.Size = new Size(210, 28);
comboBoxAudience.TabIndex = 11;
//
// comboBoxTypeWeek
//
comboBoxTypeWeek.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxTypeWeek.FormattingEnabled = true;
comboBoxTypeWeek.Location = new Point(245, 204);
comboBoxTypeWeek.Name = "comboBoxTypeWeek";
comboBoxTypeWeek.Size = new Size(210, 28);
comboBoxTypeWeek.TabIndex = 12;
//
// comboBoxTypeActivity
//
comboBoxTypePair.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxTypePair.FormattingEnabled = true;
comboBoxTypePair.Location = new Point(245, 372);
comboBoxTypePair.Name = "comboBoxTypeActivity";
comboBoxTypePair.Size = new Size(210, 28);
comboBoxTypePair.TabIndex = 14;
//
// numericUpDownNumberPair
//
numericUpDownNumberPair.Location = new Point(245, 329);
numericUpDownNumberPair.Maximum = new decimal(new int[] { 8, 0, 0, 0 });
numericUpDownNumberPair.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
numericUpDownNumberPair.Name = "numericUpDownNumberPair";
numericUpDownNumberPair.Size = new Size(210, 27);
numericUpDownNumberPair.TabIndex = 15;
numericUpDownNumberPair.Value = new decimal(new int[] { 1, 0, 0, 0 });
//
// numericUpDownNumberDay
//
numericUpDownNumberDay.Location = new Point(245, 283);
numericUpDownNumberDay.Maximum = new decimal(new int[] { 7, 0, 0, 0 });
numericUpDownNumberDay.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
numericUpDownNumberDay.Name = "numericUpDownNumberDay";
numericUpDownNumberDay.Size = new Size(210, 27);
numericUpDownNumberDay.TabIndex = 16;
numericUpDownNumberDay.Value = new decimal(new int[] { 1, 0, 0, 0 });
//
// buttonSave
//
buttonSave.Location = new Point(34, 430);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(116, 29);
buttonSave.TabIndex = 17;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(339, 430);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(116, 29);
buttonCancel.TabIndex = 18;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// labelDateDay
//
labelDateDay.AutoSize = true;
labelDateDay.Location = new Point(34, 251);
labelDateDay.Name = "labelDateDay";
labelDateDay.Size = new Size(73, 20);
labelDateDay.TabIndex = 19;
labelDateDay.Text = "Дата дня:";
//
// dateTimePickerDateDay
//
dateTimePickerDateDay.Location = new Point(245, 246);
dateTimePickerDateDay.Name = "dateTimePickerDateDay";
dateTimePickerDateDay.Size = new Size(210, 27);
dateTimePickerDateDay.TabIndex = 20;
//
// FormCompilingSchedule
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(482, 487);
Controls.Add(dateTimePickerDateDay);
Controls.Add(labelDateDay);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(numericUpDownNumberDay);
Controls.Add(numericUpDownNumberPair);
Controls.Add(comboBoxTypePair);
Controls.Add(comboBoxTypeWeek);
Controls.Add(comboBoxAudience);
Controls.Add(comboBoxTeacher);
Controls.Add(comboBoxGroup);
Controls.Add(comboBoxDiscipline);
Controls.Add(labelTypeActivity);
Controls.Add(labelNumberPair);
Controls.Add(labelTypeWeek);
Controls.Add(labelNumberDay);
Controls.Add(labelGroupStudents);
Controls.Add(labelAudience);
Controls.Add(labelDiscipline);
Controls.Add(labelEducator);
Name = "FormCompilingSchedule";
StartPosition = FormStartPosition.CenterParent;
Text = "Составление расписания";
((System.ComponentModel.ISupportInitialize)numericUpDownNumberPair).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownNumberDay).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelEducator;
private Label labelDiscipline;
private Label labelAudience;
private Label labelGroupStudents;
private Label labelNumberDay;
private Label labelTypeWeek;
private Label labelNumberPair;
private Label labelTypeActivity;
private ComboBox comboBoxDiscipline;
private ComboBox comboBoxGroup;
private ComboBox comboBoxTeacher;
private ComboBox comboBoxAudience;
private ComboBox comboBoxTypeWeek;
private ComboBox comboBoxTypePair;
private NumericUpDown numericUpDownNumberPair;
private NumericUpDown numericUpDownNumberDay;
private Button buttonSave;
private Button buttonCancel;
private Label labelDateDay;
private DateTimePicker dateTimePickerDateDay;
}
}

View File

@ -0,0 +1,65 @@
using ProjectSchedule.Entities;
using ProjectSchedule.Entities.Enums;
using ProjectSchedule.Repositories;
namespace ProjectSchedule.Forms
{
public partial class FormSchedule : Form
{
private readonly IScheduleRepository _scheduleRepository;
public FormSchedule(IScheduleRepository scheduleRepository, IDisciplineRepository disciplineRepository,
ITeacherRepository teacherRepository, IGroupRepository groupRepository, IAudienceRepository audienceRepository)
{
InitializeComponent();
_scheduleRepository = scheduleRepository ??
throw new ArgumentNullException(nameof(scheduleRepository));
comboBoxTeacher.DataSource = teacherRepository.ReadTeachers();
comboBoxTeacher.DisplayMember = "FullName";
comboBoxTeacher.ValueMember = "Id";
comboBoxDiscipline.DataSource = disciplineRepository.ReadDisciplines();
comboBoxDiscipline.DisplayMember = "Name";
comboBoxDiscipline.ValueMember = "Id";
comboBoxGroup.DataSource = groupRepository.ReadGroups();
comboBoxGroup.DisplayMember = "NameGroup";
comboBoxGroup.ValueMember = "Id";
comboBoxAudience.DataSource = audienceRepository.ReadAudiences();
comboBoxAudience.DisplayMember = "Number";
comboBoxAudience.ValueMember = "Id";
comboBoxTypeWeek.DataSource = Enum.GetValues(typeof(TypeWeek));
comboBoxTypePair.DataSource = Enum.GetValues(typeof(TypePair));
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (comboBoxTeacher.SelectedIndex < 0 || comboBoxDiscipline.SelectedIndex < 0 || comboBoxGroup.SelectedIndex < 0 ||
comboBoxAudience.SelectedIndex < 0 || comboBoxTypeWeek.SelectedIndex < 1 || comboBoxTypePair.SelectedIndex < 1)
{
throw new Exception("Имеются незаполненные поля");
}
_scheduleRepository.CreateSchedule(Schedule.CreateOperation(0, (int)comboBoxTeacher.SelectedValue!,
(int)comboBoxDiscipline.SelectedValue!, (int)comboBoxGroup.SelectedValue!, (int)comboBoxAudience.SelectedValue!,
dateTimePickerDateDay.Value, (TypeWeek)comboBoxTypeWeek.SelectedItem!, Convert.ToInt32(numericUpDownNumberDay.Value),
Convert.ToInt32(numericUpDownNumberPair.Value), (TypePair)comboBoxTypePair.SelectedItem!));
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка сохранения", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
}
}

View File

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

View File

@ -0,0 +1,99 @@
namespace ProjectSchedule.Forms
{
partial class FormSchedules
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
panelButtons = new Panel();
buttonAdd = new Button();
dataGridViewData = new DataGridView();
panelButtons.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
SuspendLayout();
//
// panelButtons
//
panelButtons.Controls.Add(buttonAdd);
panelButtons.Dock = DockStyle.Right;
panelButtons.Location = new Point(1113, 0);
panelButtons.Name = "panelButtons";
panelButtons.Size = new Size(140, 484);
panelButtons.TabIndex = 3;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.Add;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(24, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(94, 66);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.RowHeadersWidth = 51;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(1113, 484);
dataGridViewData.TabIndex = 4;
//
// FormCompilingSchedules
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1253, 484);
Controls.Add(dataGridViewData);
Controls.Add(panelButtons);
Name = "FormCompilingSchedules";
StartPosition = FormStartPosition.CenterParent;
Text = "Cоставление расписаний";
Load += FormSchedules_Load;
panelButtons.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
ResumeLayout(false);
}
#endregion
private Panel panelButtons;
private Button buttonAdd;
private DataGridView dataGridViewData;
}
}

View File

@ -0,0 +1,53 @@
using ProjectSchedule.Repositories;
using Unity;
namespace ProjectSchedule.Forms
{
public partial class FormSchedules : Form
{
private readonly IUnityContainer _container;
private readonly IScheduleRepository _scheduleRepository;
public FormSchedules(IUnityContainer container, IScheduleRepository scheduleRepository)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
_scheduleRepository = scheduleRepository ??
throw new ArgumentNullException(nameof(scheduleRepository));
}
private void FormSchedules_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormSchedule>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _scheduleRepository.ReadSchedules();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["DateDay"].DefaultCellStyle.Format = "dd.MM.yyyy";
}
}
}

View File

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

View File

@ -0,0 +1,225 @@
namespace ProjectSchedule.Forms
{
partial class FormStudingPlanSupplement
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
comboBoxGroup = new ComboBox();
labelGroupStudents = new Label();
labelNameCurriculum = new Label();
labelSemester = new Label();
textBoxNameCurriculum = new TextBox();
buttonSave = new Button();
buttonCancel = new Button();
textBoxSemester = new TextBox();
groupBoxDisciplines = new GroupBox();
dataGridViewDisciplines = new DataGridView();
ColumnDiscipline = new DataGridViewComboBoxColumn();
ColumnQuantityLectures = new DataGridViewTextBoxColumn();
ColumnQuantityPractices = new DataGridViewTextBoxColumn();
labelDateAdoptionPlan = new Label();
dateTimePickerDateAdoptionPlan = new DateTimePicker();
groupBoxDisciplines.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewDisciplines).BeginInit();
SuspendLayout();
//
// comboBoxGroupStudents
//
comboBoxGroup.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxGroup.FormattingEnabled = true;
comboBoxGroup.Location = new Point(252, 6);
comboBoxGroup.Name = "comboBoxGroupStudents";
comboBoxGroup.Size = new Size(218, 28);
comboBoxGroup.TabIndex = 1;
//
// labelGroupStudents
//
labelGroupStudents.AutoSize = true;
labelGroupStudents.Location = new Point(12, 9);
labelGroupStudents.Name = "labelGroupStudents";
labelGroupStudents.Size = new Size(133, 20);
labelGroupStudents.TabIndex = 3;
labelGroupStudents.Text = "Группа студентов:";
//
// labelNameCurriculum
//
labelNameCurriculum.AutoSize = true;
labelNameCurriculum.Location = new Point(12, 46);
labelNameCurriculum.Name = "labelNameCurriculum";
labelNameCurriculum.Size = new Size(230, 20);
labelNameCurriculum.TabIndex = 4;
labelNameCurriculum.Text = "Название учебной программы:";
//
// labelSemester
//
labelSemester.AutoSize = true;
labelSemester.Location = new Point(12, 83);
labelSemester.Name = "labelSemester";
labelSemester.Size = new Size(70, 20);
labelSemester.TabIndex = 7;
labelSemester.Text = "Семестр:";
//
// textBoxNameCurriculum
//
textBoxNameCurriculum.Location = new Point(252, 43);
textBoxNameCurriculum.Name = "textBoxNameCurriculum";
textBoxNameCurriculum.Size = new Size(218, 27);
textBoxNameCurriculum.TabIndex = 8;
//
// buttonSave
//
buttonSave.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonSave.Location = new Point(12, 522);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(116, 29);
buttonSave.TabIndex = 12;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonCancel.Location = new Point(354, 522);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(116, 29);
buttonCancel.TabIndex = 13;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// textBoxSemester
//
textBoxSemester.Location = new Point(252, 80);
textBoxSemester.Name = "textBoxSemester";
textBoxSemester.Size = new Size(218, 27);
textBoxSemester.TabIndex = 15;
//
// groupBoxDisciplines
//
groupBoxDisciplines.Controls.Add(dataGridViewDisciplines);
groupBoxDisciplines.Location = new Point(12, 155);
groupBoxDisciplines.Name = "groupBoxDisciplines";
groupBoxDisciplines.Size = new Size(458, 343);
groupBoxDisciplines.TabIndex = 16;
groupBoxDisciplines.TabStop = false;
groupBoxDisciplines.Text = "Дисциплины";
//
// dataGridViewDisciplines
//
dataGridViewDisciplines.AllowUserToResizeColumns = false;
dataGridViewDisciplines.AllowUserToResizeRows = false;
dataGridViewDisciplines.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewDisciplines.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewDisciplines.Columns.AddRange(new DataGridViewColumn[] { ColumnDiscipline, ColumnQuantityLectures, ColumnQuantityPractices });
dataGridViewDisciplines.Dock = DockStyle.Fill;
dataGridViewDisciplines.Location = new Point(3, 23);
dataGridViewDisciplines.MultiSelect = false;
dataGridViewDisciplines.Name = "dataGridViewDisciplines";
dataGridViewDisciplines.RowHeadersVisible = false;
dataGridViewDisciplines.RowHeadersWidth = 51;
dataGridViewDisciplines.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewDisciplines.Size = new Size(452, 317);
dataGridViewDisciplines.TabIndex = 0;
//
// ColumnDiscipline
//
ColumnDiscipline.HeaderText = "Дисциплина";
ColumnDiscipline.MinimumWidth = 6;
ColumnDiscipline.Name = "ColumnDiscipline";
//
// ColumnQuantityLectures
//
ColumnQuantityLectures.HeaderText = "Количество лекций";
ColumnQuantityLectures.MinimumWidth = 6;
ColumnQuantityLectures.Name = "ColumnQuantityLectures";
//
// ColumnQuantityPractices
//
ColumnQuantityPractices.HeaderText = "Количество практик";
ColumnQuantityPractices.MinimumWidth = 6;
ColumnQuantityPractices.Name = "ColumnQuantityPractices";
//
// labelDateAdoptionPlan
//
labelDateAdoptionPlan.AutoSize = true;
labelDateAdoptionPlan.Location = new Point(15, 122);
labelDateAdoptionPlan.Name = "labelDateAdoptionPlan";
labelDateAdoptionPlan.Size = new Size(161, 20);
labelDateAdoptionPlan.TabIndex = 17;
labelDateAdoptionPlan.Text = "Дата принятия плана:";
//
// dateTimePickerDateAdoptionPlan
//
dateTimePickerDateAdoptionPlan.Location = new Point(252, 117);
dateTimePickerDateAdoptionPlan.Name = "dateTimePickerDateAdoptionPlan";
dateTimePickerDateAdoptionPlan.Size = new Size(218, 27);
dateTimePickerDateAdoptionPlan.TabIndex = 18;
//
// FormCurriculumSupplement
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(482, 563);
Controls.Add(dateTimePickerDateAdoptionPlan);
Controls.Add(labelDateAdoptionPlan);
Controls.Add(groupBoxDisciplines);
Controls.Add(textBoxSemester);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxNameCurriculum);
Controls.Add(labelSemester);
Controls.Add(labelNameCurriculum);
Controls.Add(labelGroupStudents);
Controls.Add(comboBoxGroup);
Name = "FormCurriculumSupplement";
StartPosition = FormStartPosition.CenterParent;
Text = "Дополнение учебного плана";
groupBoxDisciplines.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridViewDisciplines).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox comboBoxGroup;
private Label labelGroupStudents;
private Label labelNameCurriculum;
private Label labelSemester;
private TextBox textBoxNameCurriculum;
private Button buttonSave;
private Button buttonCancel;
private TextBox textBoxSemester;
private GroupBox groupBoxDisciplines;
private DataGridView dataGridViewDisciplines;
private DataGridViewComboBoxColumn ColumnDiscipline;
private DataGridViewTextBoxColumn ColumnQuantityLectures;
private DataGridViewTextBoxColumn ColumnQuantityPractices;
private Label labelDateAdoptionPlan;
private DateTimePicker dateTimePickerDateAdoptionPlan;
}
}

View File

@ -0,0 +1,74 @@
using ProjectSchedule.Entities;
using ProjectSchedule.Repositories;
using ProjectSchedule.Repositories.Implementations;
namespace ProjectSchedule.Forms
{
public partial class FormStudingPlanSupplement : Form
{
private readonly IStudingPlanSupplementRepository _studingPlanSupplementRepository;
public FormStudingPlanSupplement(IStudingPlanSupplementRepository studingPlanSupplementRepository,
IDisciplineRepository disciplineRepository, IGroupRepository groupRepository)
{
InitializeComponent();
_studingPlanSupplementRepository = studingPlanSupplementRepository ??
throw new ArgumentNullException(nameof(studingPlanSupplementRepository));
comboBoxGroup.DataSource = groupRepository.ReadGroups();
comboBoxGroup.DisplayMember = "Name";
comboBoxGroup.ValueMember = "Id";
ColumnDiscipline.DataSource = disciplineRepository.ReadDisciplines();
ColumnDiscipline.DisplayMember = "Name";
ColumnDiscipline.ValueMember = "Id";
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (dataGridViewDisciplines.RowCount < 1 || comboBoxGroup.SelectedIndex < 0 ||
string.IsNullOrWhiteSpace(textBoxNameCurriculum.Text) || string.IsNullOrWhiteSpace(textBoxSemester.Text))
{
throw new Exception("Имеются незаполненные поля");
}
_studingPlanSupplementRepository.CreateStudingPlanSupplement(StudingPlanSupplement.CreateOperation(0,
(int)comboBoxGroup.SelectedValue!, textBoxNameCurriculum.Text, textBoxSemester.Text,
dateTimePickerDateAdoptionPlan.Value, CreateListDisciplineStudingPlanSupplementsFromDataGrid()));
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private List<DisciplineStudingPlanSupplement> CreateListDisciplineStudingPlanSupplementsFromDataGrid()
{
var list = new List<DisciplineStudingPlanSupplement>();
foreach (DataGridViewRow row in dataGridViewDisciplines.Rows)
{
if (row.Cells["ColumnDiscipline"].Value == null || row.Cells["ColumnQuantityLectures"].Value == null ||
row.Cells["ColumnQuantityPractices"].Value == null)
{
continue;
}
list.Add(DisciplineStudingPlanSupplement.CreateElement(0, Convert.ToInt32(row.Cells["ColumnDiscipline"].Value),
Convert.ToInt32(row.Cells["ColumnQuantityLectures"].Value),
Convert.ToInt32(row.Cells["ColumnQuantityPractices"].Value)));
}
return list.GroupBy(x => x.DisciplineId, x => new { x.LecturesCount, x.PracticesCount }, (id, group) =>
DisciplineStudingPlanSupplement.CreateElement(0, id, group.Sum(x => x.LecturesCount), group.Sum(x => x.PracticesCount))).ToList();
}
}
}

View File

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

View File

@ -0,0 +1,113 @@
namespace ProjectSchedule.Forms
{
partial class FormStudingPlanSupplements
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
panelButtons = new Panel();
buttonDel = new Button();
buttonAdd = new Button();
dataGridViewData = new DataGridView();
panelButtons.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
SuspendLayout();
//
// panelButtons
//
panelButtons.Controls.Add(buttonDel);
panelButtons.Controls.Add(buttonAdd);
panelButtons.Dock = DockStyle.Right;
panelButtons.Location = new Point(764, 0);
panelButtons.Name = "panelButtons";
panelButtons.Size = new Size(140, 453);
panelButtons.TabIndex = 2;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.Del;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(24, 372);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(94, 66);
buttonDel.TabIndex = 4;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.Add;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(24, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(94, 66);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.RowHeadersWidth = 51;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(764, 453);
dataGridViewData.TabIndex = 3;
//
// FormCurriculumSupplements
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(904, 453);
Controls.Add(dataGridViewData);
Controls.Add(panelButtons);
Name = "FormCurriculumSupplements";
StartPosition = FormStartPosition.CenterParent;
Text = "Дополнения учебного плана";
Load += FormStudingPlanSupplements_Load;
panelButtons.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
ResumeLayout(false);
}
#endregion
private Panel panelButtons;
private Button buttonDel;
private Button buttonAdd;
private DataGridView dataGridViewData;
}
}

View File

@ -0,0 +1,90 @@
using ProjectSchedule.Repositories;
using Unity;
namespace ProjectSchedule.Forms
{
public partial class FormStudingPlanSupplements : Form
{
private readonly IUnityContainer _container;
private readonly IStudingPlanSupplementRepository _studingPlanSupplementRepository;
public FormStudingPlanSupplements(IUnityContainer container, IStudingPlanSupplementRepository studingPlanSupplementRepository)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
_studingPlanSupplementRepository = studingPlanSupplementRepository ??
throw new ArgumentNullException(nameof(studingPlanSupplementRepository));
}
private void FormStudingPlanSupplements_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormStudingPlanSupplement>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_studingPlanSupplementRepository.DeleteStudingPlanSupplement(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _studingPlanSupplementRepository.ReadStudingPlanSupplements();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["DateApprovePlan"].DefaultCellStyle.Format = "dd MMMM yyyy";
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewData.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewData.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

View File

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

View File

@ -0,0 +1,140 @@
namespace ProjectSchedule.Forms
{
partial class FormTeacher
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelSurname = new Label();
labelName = new Label();
labelPatronymic = new Label();
textBoxName = new TextBox();
textBoxSurname = new TextBox();
textBoxPatronymic = new TextBox();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// labelSurname
//
labelSurname.AutoSize = true;
labelSurname.Location = new Point(21, 30);
labelSurname.Name = "labelSurname";
labelSurname.Size = new Size(76, 20);
labelSurname.TabIndex = 0;
labelSurname.Text = "Фамилия:";
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(21, 78);
labelName.Name = "labelName";
labelName.Size = new Size(42, 20);
labelName.TabIndex = 1;
labelName.Text = "Имя:";
//
// labelPatronymic
//
labelPatronymic.AutoSize = true;
labelPatronymic.Location = new Point(21, 133);
labelPatronymic.Name = "labelPatronymic";
labelPatronymic.Size = new Size(75, 20);
labelPatronymic.TabIndex = 2;
labelPatronymic.Text = "Отчество:";
//
// textBoxName
//
textBoxName.Location = new Point(161, 75);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(232, 27);
textBoxName.TabIndex = 3;
//
// textBoxSurname
//
textBoxSurname.Location = new Point(161, 27);
textBoxSurname.Name = "textBoxSurname";
textBoxSurname.Size = new Size(232, 27);
textBoxSurname.TabIndex = 4;
//
// textBoxPatronymic
//
textBoxPatronymic.Location = new Point(161, 130);
textBoxPatronymic.Name = "textBoxPatronymic";
textBoxPatronymic.Size = new Size(232, 27);
textBoxPatronymic.TabIndex = 5;
//
// buttonSave
//
buttonSave.Location = new Point(21, 200);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(116, 29);
buttonSave.TabIndex = 6;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(277, 200);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(116, 29);
buttonCancel.TabIndex = 7;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormEducator
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(405, 246);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxPatronymic);
Controls.Add(textBoxSurname);
Controls.Add(textBoxName);
Controls.Add(labelPatronymic);
Controls.Add(labelName);
Controls.Add(labelSurname);
Name = "FormEducator";
StartPosition = FormStartPosition.CenterParent;
Text = "Преподаватель";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelSurname;
private Label labelName;
private Label labelPatronymic;
private TextBox textBoxName;
private TextBox textBoxSurname;
private TextBox textBoxPatronymic;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,71 @@
using ProjectSchedule.Entities;
using ProjectSchedule.Repositories;
namespace ProjectSchedule.Forms;
public partial class FormTeacher : Form
{
private readonly ITeacherRepository _teacherRepository;
private int? _teacherId;
public int Id
{
set
{
try
{
var teacher = _teacherRepository.ReadTeacherById(value);
if (teacher == null)
{
throw new InvalidDataException(nameof(teacher));
}
textBoxSurname.Text = teacher.Surname;
textBoxName.Text = teacher.Name;
textBoxPatronymic.Text = teacher.Patronymic;
_teacherId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormTeacher(ITeacherRepository teacherRepository)
{
InitializeComponent();
_teacherRepository = teacherRepository ??
throw new ArgumentNullException(nameof(teacherRepository));
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxSurname.Text) || string.IsNullOrWhiteSpace(textBoxName.Text) ||
string.IsNullOrWhiteSpace(textBoxPatronymic.Text))
{
throw new Exception("Имеются незаполненные поля");
}
if (_teacherId.HasValue)
{
_teacherRepository.UpdateTeacher(CreateTeacher(_teacherId.Value));
}
else
{
_teacherRepository.CreateTeacher(CreateTeacher(0));
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private Teacher CreateTeacher(int id) =>
Teacher.CreateEntity(id, textBoxSurname.Text, textBoxName.Text, textBoxPatronymic.Text);
}

View File

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

View File

@ -0,0 +1,127 @@
namespace ProjectSchedule.Forms
{
partial class FormTeachers
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
panelButtons = new Panel();
buttonDel = new Button();
buttonUpd = new Button();
buttonAdd = new Button();
dataGridViewData = new DataGridView();
panelButtons.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
SuspendLayout();
//
// panelButtons
//
panelButtons.Controls.Add(buttonDel);
panelButtons.Controls.Add(buttonUpd);
panelButtons.Controls.Add(buttonAdd);
panelButtons.Dock = DockStyle.Right;
panelButtons.Location = new Point(642, 0);
panelButtons.Name = "panelButtons";
panelButtons.Size = new Size(140, 453);
panelButtons.TabIndex = 1;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.Del;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(24, 194);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(94, 66);
buttonDel.TabIndex = 4;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonUpd
//
buttonUpd.BackgroundImage = Properties.Resources.Upd;
buttonUpd.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpd.Location = new Point(24, 106);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(94, 66);
buttonUpd.TabIndex = 3;
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.Add;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(24, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(94, 66);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.RowHeadersWidth = 51;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(642, 453);
dataGridViewData.TabIndex = 2;
//
// FormEducators
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(782, 453);
Controls.Add(dataGridViewData);
Controls.Add(panelButtons);
Name = "FormEducators";
StartPosition = FormStartPosition.CenterParent;
Text = "Преподаватели";
Load += FormTeachers_Load;
panelButtons.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
ResumeLayout(false);
}
#endregion
private Panel panelButtons;
private Button buttonDel;
private Button buttonUpd;
private Button buttonAdd;
private DataGridView dataGridViewData;
}
}

View File

@ -0,0 +1,109 @@
using ProjectSchedule.Repositories;
using Unity;
namespace ProjectSchedule.Forms
{
public partial class FormTeachers : Form
{
private readonly IUnityContainer _container;
private readonly ITeacherRepository _teacherRepository;
public FormTeachers(IUnityContainer container, ITeacherRepository teacherRepository)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
_teacherRepository = teacherRepository ??
throw new ArgumentNullException(nameof(teacherRepository));
}
private void FormTeachers_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormTeacher>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FormTeacher>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_teacherRepository.DeleteTeacher(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _teacherRepository.ReadTeachers();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["FullName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewData.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewData.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

View File

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

View File

@ -1,3 +1,12 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using ProjectSchedule.Repositories;
using ProjectSchedule.Repositories.Implementations;
using Serilog;
using Unity;
using Unity.Lifetime;
using Unity.Microsoft.Logging;
namespace ProjectSchedule
{
internal static class Program
@ -11,7 +20,33 @@ namespace ProjectSchedule
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
Application.Run(CreateUnityContainer().Resolve<FormSchedule>());
}
private static IUnityContainer CreateUnityContainer()
{
var container = new UnityContainer();
container.AddExtension(new LoggingExtension(CreateLoggerFactory()));
container.RegisterType<IAudienceRepository, AudienceRepository>(new TransientLifetimeManager());
container.RegisterType<ITeacherRepository, TeacherRepository>(new TransientLifetimeManager());
container.RegisterType<IGroupRepository, GroupRepository>(new TransientLifetimeManager());
container.RegisterType<IStudingPlanSupplementRepository, StudingPlanSupplementRepository>(new TransientLifetimeManager());
container.RegisterType<IDisciplineRepository, DisciplineRepository>(new TransientLifetimeManager());
container.RegisterType<IScheduleRepository, ScheduleRepository>(new TransientLifetimeManager());
container.RegisterType<IConnectionString, ConnectionString>(new SingletonLifetimeManager());
return container;
}
private static LoggerFactory CreateLoggerFactory()
{
var loggerFactory = new LoggerFactory();
loggerFactory.AddSerilog(new LoggerConfiguration()
.ReadFrom.Configuration(new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build())
.CreateLogger());
return loggerFactory;
}
}
}

View File

@ -8,4 +8,22 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="DocumentFormat.OpenXml" Version="3.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Npgsql" Version="9.0.2" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
<PackageReference Include="Serilog" Version="4.2.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.9.0" />
<PackageReference Include="Unity.Container" Version="5.11.11" />
<PackageReference Include="Unity.Microsoft.Logging" Version="5.11.1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,103 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ProjectSchedule.Properties {
using System;
/// <summary>
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
/// </summary>
// Этот класс создан автоматически классом StronglyTypedResourceBuilder
// с помощью такого средства, как ResGen или Visual Studio.
// Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen
// с параметром /str или перестройте свой проект VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ProjectSchedule.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Add {
get {
object obj = ResourceManager.GetObject("добавить", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Del {
get {
object obj = ResourceManager.GetObject("удалить", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Upd {
get {
object obj = ResourceManager.GetObject("редактировать", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Bg {
get {
object obj = ResourceManager.GetObject("фон", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

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

View File

@ -0,0 +1,46 @@
using Microsoft.Extensions.Logging;
using ProjectSchedule.Repositories;
namespace ProjectSchedule.Reports;
internal class ChartReport
{
private readonly IScheduleRepository _scheduleRepository;
private readonly ILogger<ChartReport> _logger;
public ChartReport(IScheduleRepository scheduleRepository, ILogger<ChartReport> logger)
{
_scheduleRepository = scheduleRepository ??
throw new ArgumentNullException(nameof(scheduleRepository));
_logger = logger ??
throw new ArgumentNullException(nameof(logger));
}
public bool CreateChart(string filePath, DateTime dateTime)
{
try
{
new PdfBuilder(filePath)
.AddHeader($"Количество пар на {dateTime:dd MMMM yyyy}")
.AddPieChart("Группы студентов", GetData(dateTime))
.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<(string Caption, double Value)> GetData(DateTime dateTime)
{
return _scheduleRepository
.ReadSchedules(dateForm: dateTime.Date, dateTo: dateTime.Date.AddDays(1))
.GroupBy(x => x.NameGroup, (key, group) => new { NameGroup = key, Count = group.Count() })
.Select(x => (x.NameGroup, (double)x.Count))
.ToList();
}
}

View File

@ -0,0 +1,111 @@
using Microsoft.Extensions.Logging;
using ProjectSchedule.Repositories;
namespace ProjectSchedule.Reports;
internal class DocReport
{
private readonly IAudienceRepository _audienceRepository;
private readonly IDisciplineRepository _disciplineRepository;
private readonly ITeacherRepository _teacherRepository;
private readonly IGroupRepository _groupRepository;
private readonly ILogger<DocReport> _logger;
public DocReport(IAudienceRepository audienceRepository,
IDisciplineRepository disciplineRepository, ITeacherRepository teacherRepository,
IGroupRepository groupRepository, ILogger<DocReport> logger)
{
_audienceRepository = audienceRepository ?? throw new ArgumentNullException(nameof(audienceRepository));
_disciplineRepository = disciplineRepository ?? throw new ArgumentNullException(nameof(disciplineRepository));
_teacherRepository = teacherRepository ?? throw new ArgumentNullException(nameof(teacherRepository));
_groupRepository = groupRepository ?? throw new ArgumentNullException(nameof(groupRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateDoc(string filePath, bool includeAudiences, bool includeDisciplines,
bool includeTeachers, bool includeGroupsStudents)
{
try
{
var builder = new WordBuilder(filePath)
.AddHeader("Документ со справочниками");
if (includeAudiences)
{
builder.AddParagraph("Аудитории")
.AddTable([1200, 2400, 1200], GetAudiences());
}
if (includeDisciplines)
{
builder.AddParagraph("Дисциплины")
.AddTable([2400], GetDisciplines());
}
if (includeTeachers)
{
builder.AddParagraph("Преподаватели")
.AddTable([2400, 2400, 2400], GetTeachers());
}
if (includeGroupsStudents)
{
builder.AddParagraph("Группы студентов")
.AddTable([1200, 1200, 1200], GetGroupsStudents());
}
builder.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<string[]> GetAudiences()
{
return [
["Номер аудитории", "Тип аудитории", "Количество мест"],
.. _audienceRepository
.ReadAudiences()
.Select(x => new string[] { x.Number, x.TypeAudience.ToString(), x.SeatsCount.ToString() }),
];
}
private List<string[]> GetDisciplines()
{
return [
["Название дисциплины"],
.. _disciplineRepository
.ReadDisciplines()
.Select(x => new string[] { x.Name }),
];
}
private List<string[]> GetTeachers()
{
return [
["Фамилия", "Имя", "Отчество"],
.. _teacherRepository
.ReadTeachers()
.Select(x => new string[] { x.Surname, x.Name, x.Patronymic }),
];
}
private List<string[]> GetGroupsStudents()
{
return [
["Название группы", "Номер группы", "Количество студентов"],
.. _groupRepository
.ReadGroups()
.Select(x => new string[] { x.Name, x.GroupNumber, x.StudentsCount.ToString() }),
];
}
}

View File

@ -0,0 +1,322 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace ProjectSchedule.Reports;
internal 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 count)
{
CreateCell(startIndex, _rowIndex, header, StyleIndex.BoldTextWithoutBorder);
for (int i = startIndex + 1; i < startIndex + count; ++i)
{
CreateCell(i, _rowIndex, "", StyleIndex.SimpleTextWithoutBorder);
}
_mergeCells.Append(new MergeCell()
{
Reference =
new StringValue($"{GetExcelColumnName(startIndex)}{_rowIndex}:{GetExcelColumnName(startIndex + count - 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<string[]> 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("columnsWidths.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>();
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<SheetData>().First());
}
}
private static void GenerateStyle(WorkbookPart workbookPart)
{
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
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>(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>(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>(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<Row>().FirstOrDefault(r => r.RowIndex! == rowIndex);
if (row == null)
{
row = new Row() { RowIndex = rowIndex };
_sheetData.Append(row);
}
var newCell = row.Elements<Cell>()
.FirstOrDefault(c => c.CellReference != null && c.CellReference.Value == columnName + rowIndex);
if (newCell == null)
{
Cell? refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
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;
}
}

View File

@ -0,0 +1,92 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering;
using System.Text;
namespace ProjectSchedule.Reports;
internal class PdfBuilder
{
private readonly string _filePath;
private readonly Document _document;
public PdfBuilder(string filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
_filePath = filePath;
_document = new Document();
DefineStyles();
}
public PdfBuilder AddHeader(string header)
{
_document.AddSection().AddParagraph(header, "NormalBold");
return this;
}
public PdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data)
{
if (data == null || data.Count == 0)
{
return this;
}
var chart = new Chart(ChartType.Pie2D);
var series = chart.SeriesCollection.AddSeries();
series.Add(data.Select(x => x.Value).ToArray());
var xseries = chart.XValues.AddXSeries();
xseries.Add(data.Select(x => x.Caption).ToArray());
chart.DataLabel.Type = DataLabelType.Percent;
chart.DataLabel.Position = DataLabelPosition.OutsideEnd;
chart.Width = Unit.FromCentimeter(16);
chart.Height = Unit.FromCentimeter(12);
chart.TopArea.AddParagraph(title);
chart.XAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.HasMajorGridlines = true;
chart.PlotArea.LineFormat.Width = 1;
chart.PlotArea.LineFormat.Visible = true;
chart.TopArea.AddLegend();
_document.LastSection.Add(chart);
return this;
}
public void Build()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(_filePath);
}
private void DefineStyles()
{
var headerStyle = _document.Styles.AddStyle("NormalBold", "Normal");
headerStyle.Font.Bold = true;
headerStyle.Font.Size = 14;
}
}

View File

@ -0,0 +1,89 @@
using Microsoft.Extensions.Logging;
using ProjectSchedule.Entities;
using ProjectSchedule.Entities.Enums;
using ProjectSchedule.Repositories;
namespace ProjectSchedule.Reports;
internal class TableReport
{
private readonly IStudingPlanSupplementRepository _studingPlanSupplementRepository;
private readonly IScheduleRepository _scheduleRepository;
private readonly ILogger<TableReport> _logger;
internal static readonly string[] item = ["Дата", "Дисциплина", "Группа студентов", "Количество лекций",
"Количество практик", "Прошедших лекций", "Прошедших практик"];
public TableReport(IStudingPlanSupplementRepository studingPlanSupplementRepository,
IScheduleRepository scheduleRepository, ILogger<TableReport> logger)
{
_studingPlanSupplementRepository = studingPlanSupplementRepository ??
throw new ArgumentNullException(nameof(studingPlanSupplementRepository));
_scheduleRepository = scheduleRepository ??
throw new ArgumentNullException(nameof(scheduleRepository));
_logger = logger ??
throw new ArgumentNullException(nameof(logger));
}
public bool CreateTable(string filePath, int disciplineId, DateTime startDate, DateTime endDate)
{
try
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по прохождению дисциплин", 0, 7)
.AddParagraph($"за период c {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0)
.AddTable([10, 10, 10, 10, 10, 10, 10], GetData(disciplineId, startDate, endDate))
.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<string[]> GetData(int disciplineId, DateTime startDate, DateTime endDate)
{
var data = _studingPlanSupplementRepository
.ReadStudingPlanSupplements(dateForm: startDate, disciplineId: disciplineId)
.Select(x => new {
Date = x.DateApprovePlan,
Discipline = x.DisciplineStudingPlanSupplements.FirstOrDefault(y => y.DisciplineId == disciplineId)?.NameDiscipline ?? string.Empty,
x.NameGroup,
CountLectures = x.DisciplineStudingPlanSupplements.FirstOrDefault(y => y.DisciplineId == disciplineId)?.LecturesCount,
CountPractices = x.DisciplineStudingPlanSupplements.FirstOrDefault(y => y.DisciplineId == disciplineId)?.PracticesCount,
PastLectures = (int?)null,
PastPractices = (int?)null
})
.Union(
_scheduleRepository
.ReadSchedules(dateForm: startDate, dateTo: endDate, disciplineId: disciplineId)
.GroupBy(x => new { x.DateDay, x.NameDiscipline, x.NameGroup })
.Select(g => new {
Date = g.Key.DateDay,
Discipline = g.Key.NameDiscipline ?? string.Empty,
g.Key.NameGroup,
CountLectures = (int?)null,
CountPractices = (int?)null,
PastLectures = g.Count(s => s.TypePair == TypePair.Lecture) == 0 ? (int?)null : g.Count(s => s.TypePair == TypePair.Lecture),
PastPractices = g.Count(s => s.TypePair == TypePair.Practice) == 0 ? (int?)null : g.Count(s => s.TypePair == TypePair.Practice)
}))
.OrderBy(x => x.Date);
return
new List<string[]>() { item }
.Union(
data
.Select(x => new string[] { x.Date.ToString("dd.MM.yyyy"), x.Discipline, x.NameGroup,
x.CountLectures?.ToString("N0") ?? string.Empty, x.CountPractices?.ToString("N0") ?? string.Empty,
x.PastLectures?.ToString("N0") ?? string.Empty, x.PastPractices?.ToString("N0") ?? string.Empty }))
.Union(
[["Всего", "", "", data.Sum(x => x.CountLectures ?? 0).ToString("N0"), data.Sum(x => x.CountPractices ?? 0).ToString("N0"),
data.Sum(x => x.PastLectures ?? 0).ToString("N0"), data.Sum(x => x.PastPractices ?? 0).ToString("N0")]])
.ToList();
}
}

View File

@ -0,0 +1,105 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
namespace ProjectSchedule.Reports;
internal 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());
run.AppendChild(new RunProperties(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<string[]> 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>(BorderValues.Single), Size = 12 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(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;
}
}

View File

@ -0,0 +1,17 @@
using ProjectSchedule.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Repositories;
public interface IAudienceRepository
{
IEnumerable<Audience> ReadAudiences();
Audience ReadAudienceById(int id);
void CreateAudience(Audience audience);
void UpdateAudience(Audience audience);
void DeleteAudience(int id);
}

View File

@ -0,0 +1,6 @@
namespace ProjectSchedule.Repositories;
public interface IConnectionString
{
public string ConnectionString { get; }
}

View File

@ -0,0 +1,17 @@
using ProjectSchedule.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Repositories;
public interface IDisciplineRepository
{
IEnumerable<Discipline> ReadDisciplines();
Discipline ReadDisciplineById(int id);
void CreateDiscipline(Discipline discipline);
void UpdateDiscipline(Discipline discipline);
void DeleteDiscipline(int id);
}

View File

@ -0,0 +1,17 @@
using ProjectSchedule.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Repositories;
public interface IGroupRepository
{
IEnumerable<Group> ReadGroups();
Group ReadGroupById(int id);
void CreateGroup(Group group);
void UpdateGroup(Group group);
void DeleteGroup(int id);
}

View File

@ -0,0 +1,15 @@
using ProjectSchedule.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Repositories;
public interface IScheduleRepository
{
IEnumerable<Schedule> ReadSchedules(DateTime? dateForm = null, DateTime? dateTo = null,
int? teacherId = null, int? disciplineId = null, int? groupStudentsId = null, int? audienceId = null);
void CreateSchedule(Schedule schedule);
}

View File

@ -0,0 +1,16 @@
using ProjectSchedule.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Repositories;
public interface IStudingPlanSupplementRepository
{
IEnumerable<StudingPlanSupplement> ReadStudingPlanSupplements(DateTime? dateForm = null,
int? disciplineId = null, int? groupStudentsId = null);
void CreateStudingPlanSupplement(StudingPlanSupplement studingPlanSupplement);
void DeleteStudingPlanSupplement(int id);
}

View File

@ -0,0 +1,17 @@
using ProjectSchedule.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectSchedule.Repositories;
public interface ITeacherRepository
{
IEnumerable<Teacher> ReadTeachers();
Teacher ReadTeacherById(int id);
void CreateTeacher(Teacher teacher);
void UpdateTeacher(Teacher teacher);
void DeleteTeacher(int id);
}

View File

@ -0,0 +1,120 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectSchedule.Entities;
namespace ProjectSchedule.Repositories.Implementations;
public class AudienceRepository : IAudienceRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<AudienceRepository> _logger;
public AudienceRepository(IConnectionString connectionString, ILogger<AudienceRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateAudience(Audience audience)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(audience));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Audience (Number, TypeAudience, SeatsCount)
VALUES (@Number, @TypeAudience, @SeatsCount)";
connection.Execute(queryInsert, audience);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void UpdateAudience(Audience audience)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(audience));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Audience
SET
Number=@Number,
TypeAudience=@TypeAudience,
SeatsCount=@SeatsCount
WHERE Id=@Id";
connection.Execute(queryUpdate, audience);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
public void DeleteAudience(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Audience
WHERE Id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Audience ReadAudienceById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Audience
WHERE Id=@id";
var audience = connection.QueryFirst<Audience>(querySelect, new { id });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(audience));
return audience;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Audience> ReadAudiences()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Audience";
var audiences = connection.Query<Audience>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(audiences));
return audiences;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@ -0,0 +1,6 @@
namespace ProjectSchedule.Repositories.Implementations;
internal class ConnectionString : IConnectionString
{
string IConnectionString.ConnectionString => "Host=127.0.0.1;Database=postgres;Username=postgres;Password=ishtuganov";
}

View File

@ -0,0 +1,118 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectSchedule.Entities;
namespace ProjectSchedule.Repositories.Implementations;
public class DisciplineRepository : IDisciplineRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<DisciplineRepository> _logger;
public DisciplineRepository(IConnectionString connectionString, ILogger<DisciplineRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateDiscipline(Discipline discipline)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(discipline));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Discipline (Name)
VALUES (@Name)";
connection.Execute(queryInsert, discipline);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void UpdateDiscipline(Discipline discipline)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(discipline));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Discipline
SET
Name=@Name
WHERE Id=@Id";
connection.Execute(queryUpdate, discipline);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
public void DeleteDiscipline(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Discipline
WHERE Id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Discipline ReadDisciplineById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Discipline
WHERE Id=@id";
var discipline = connection.QueryFirst<Discipline>(querySelect, new { id });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(discipline));
return discipline;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Discipline> ReadDisciplines()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Discipline";
var disciplines = connection.Query<Discipline>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(disciplines));
return disciplines;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@ -0,0 +1,120 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectSchedule.Entities;
namespace ProjectSchedule.Repositories.Implementations;
public class GroupRepository : IGroupRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<GroupRepository> _logger;
public GroupRepository(IConnectionString connectionString, ILogger<GroupRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateGroup(Group group)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(group));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Groups (Name, GroupNumber, StudentsCount)
VALUES (@Name, @GroupNumber, @StudentsCount)";
connection.Execute(queryInsert, group);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void UpdateGroup(Group group)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(group));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Groups
SET
Name=@Name,
GroupNumber=@GroupNumber,
StudentsCount=@StudentsCount
WHERE Id=@Id";
connection.Execute(queryUpdate, group);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
public void DeleteGroup(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Groups
WHERE Id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Group ReadGroupById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Groups
WHERE Id=@id";
var group = connection.QueryFirst<Group>(querySelect, new { id });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(group));
return group;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Group> ReadGroups()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Groups";
var groups = connection.Query<Group>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(groups));
return groups;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@ -0,0 +1,35 @@
using System.Text;
namespace ProjectSchedule.Repositories.Implementations;
internal class QueryBuilder
{
private readonly StringBuilder _builder;
public QueryBuilder()
{
_builder = new();
}
public QueryBuilder AddCondition(string condition)
{
if (_builder.Length > 0)
{
_builder.Append(" AND ");
}
_builder.Append(condition);
return this;
}
public string Build()
{
if (_builder.Length == 0)
{
return string.Empty;
}
return $"WHERE {_builder}";
}
}

View File

@ -0,0 +1,98 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectSchedule.Entities;
namespace ProjectSchedule.Repositories.Implementations;
public class ScheduleRepository : IScheduleRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<ScheduleRepository> _logger;
public ScheduleRepository(IConnectionString connectionString, ILogger<ScheduleRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateSchedule(Schedule schedule)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(schedule));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Schedule (TeacherId, DisciplineId, GroupId, AudienceId, DateDay,
TypeWeek, NumberDay, NumberPair, TypePair)
VALUES (@TeacherId, @DisciplineId, @GroupId, @AudienceId, @DateDay,
@TypeWeek, @NumberDay, @NumberPair, @TypePair)";
connection.Execute(queryInsert, schedule);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public IEnumerable<Schedule> ReadSchedules(DateTime? dateForm = null, DateTime? dateTo = null,
int? teacherId = null, int? disciplineId = null, int? groupStudentsId = null, int? audienceId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateForm.HasValue)
{
builder.AddCondition("s.DateDay >= @dateForm");
}
if (dateTo.HasValue)
{
builder.AddCondition("s.DateDay <= @dateTo");
}
if (teacherId.HasValue)
{
builder.AddCondition("s.TeacherId = @teacherId");
}
if (disciplineId.HasValue)
{
builder.AddCondition("s.DisciplineId = @disciplineId");
}
if (groupStudentsId.HasValue)
{
builder.AddCondition("s.GroupStudentsId = @groupStudentsId");
}
if (audienceId.HasValue)
{
builder.AddCondition("s.AudienceId = @audienceId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = $@"
SELECT
s.*,
CONCAT(e.Surname, ' ', e.Name, ' ', e.Patronymic) AS TeacherName,
d.Name AS NameDiscipline,
CONCAT(g.Name, '-', g.GroupNumber) AS NameGroup,
a.Number AS NumberAudience
FROM Schedule s
LEFT JOIN Teacher e ON e.Id = s.TeacherId
LEFT JOIN Discipline d ON d.Id = s.DisciplineId
LEFT JOIN Groups g ON g.Id = s.GroupId
LEFT JOIN Audience a ON a.Id = s.AudienceId
{builder.Build()}";
var schedules = connection.Query<Schedule>(querySelect,
new { dateForm, dateTo, teacherId, disciplineId, groupStudentsId, audienceId });
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(schedules));
return schedules;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@ -0,0 +1,135 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectSchedule.Entities;
namespace ProjectSchedule.Repositories.Implementations;
public class StudingPlanSupplementRepository : IStudingPlanSupplementRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<StudingPlanSupplementRepository> _logger;
public StudingPlanSupplementRepository(IConnectionString connectionString, ILogger<StudingPlanSupplementRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateStudingPlanSupplement(StudingPlanSupplement studingPlanSupplement)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(studingPlanSupplement));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
var queryInsert = @"
INSERT INTO StudingPlanSupplement (GroupId, NameStudingPlan, Semester, DateApprovePlan)
VALUES (@GroupId, @NameStudingPlan, @Semester, @DateApprovePlan);
SELECT MAX(Id) FROM StudingPlanSupplement";
var studingPlanSupplementId = connection.QueryFirst<int>(queryInsert, studingPlanSupplement, transaction);
var querySubInsert = @"
INSERT INTO Discipline_StudingPlanSupplement (StudingPlanSupplementId, DisciplineId, LecturesCount, PracticesCount)
VALUES (@StudingPlanSupplementId, @DisciplineId, @LecturesCount, @PracticesCount)";
foreach (var elem in studingPlanSupplement.DisciplineStudingPlanSupplements)
{
connection.Execute(querySubInsert, new { studingPlanSupplementId, elem.DisciplineId, elem.LecturesCount, elem.PracticesCount }, transaction);
}
transaction.Commit();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void DeleteStudingPlanSupplement(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM StudingPlanSupplement
WHERE Id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public IEnumerable<StudingPlanSupplement> ReadStudingPlanSupplements(DateTime? dateForm = null, int? disciplineId = null,
int? groupStudentsId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateForm.HasValue)
{
builder.AddCondition("sps.DateApprovePlan <= @dateForm");
}
if (groupStudentsId.HasValue)
{
builder.AddCondition("sps.GroupId = @groupStudentsId");
}
if (disciplineId.HasValue)
{
builder.AddCondition("dsps.DisciplineId = @disciplineId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = $@"
SELECT
sps.*,
CONCAT(g.Name, '-', g.GroupNumber) AS NameGroup,
dsps.DisciplineId,
dsps.LecturesCount,
dsps.PracticesCount,
d.Name AS NameDiscipline
FROM StudingPlanSupplement sps
LEFT JOIN Groups g ON g.Id = sps.GroupId
INNER JOIN Discipline_StudingPlanSupplement dsps ON dsps.StudingPlanSupplementId = sps.Id
LEFT JOIN Discipline d ON d.Id = dsps.DisciplineId
{builder.Build()}";
var supplementDict = new Dictionary<int, List<DisciplineStudingPlanSupplement>>();
var studingPlanSupplements = connection.Query<StudingPlanSupplement, DisciplineStudingPlanSupplement, StudingPlanSupplement>(querySelect,
(supplement, studingPlanSupplements) =>
{
if (!supplementDict.TryGetValue(supplement.Id, out var dsps))
{
dsps = [];
supplementDict.Add(supplement.Id, dsps);
}
dsps.Add(studingPlanSupplements);
return supplement;
}, splitOn: "DisciplineId", param: new { dateForm, disciplineId, groupStudentsId });
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(studingPlanSupplements));
return supplementDict.Select(x =>
{
var cs = studingPlanSupplements.First(y => y.Id == x.Key);
cs.SetDisciplineStudingPlanSupplements(x.Value);
return cs;
}).ToArray();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@ -0,0 +1,120 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectSchedule.Entities;
namespace ProjectSchedule.Repositories.Implementations;
public class TeacherRepository : ITeacherRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<TeacherRepository> _logger;
public TeacherRepository(IConnectionString connectionString, ILogger<TeacherRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateTeacher(Teacher teacher)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(teacher));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Teacher (Surname, Name, Patronymic)
VALUES (@Surname, @Name, @Patronymic)";
connection.Execute(queryInsert, teacher);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void UpdateTeacher(Teacher teacher)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(teacher));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Teacher
SET
Surname=@Surname,
Name=@Name,
Patronymic=@Patronymic
WHERE Id=@Id";
connection.Execute(queryUpdate, teacher);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
public void DeleteTeacher(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Teacher
WHERE Id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Teacher ReadTeacherById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Teacher
WHERE Id=@id";
var teacher = connection.QueryFirst<Teacher>(querySelect, new { id });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(teacher));
return teacher;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Teacher> ReadTeachers()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Teacher";
var teachers = connection.Query<Teacher>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(teachers));
return teachers;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,15 @@
{
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "Logs/schedule_log.txt",
"rollingInterval": "Day"
}
}
]
}
}