From 4e86563468694fcb8da14c8aa15cfd354e92f4bf Mon Sep 17 00:00:00 2001 From: danilafilippov7299 Date: Fri, 21 Jun 2024 19:36:33 +0400 Subject: [PATCH] lab6 --- Bar/Bar/FormMain.Designer.cs | 24 +- Bar/Bar/FormMain.cs | 24 +- Bar/Bar/Forms/FormImplementer.Designer.cs | 173 ++++++++++++ Bar/Bar/Forms/FormImplementer.cs | 105 ++++++++ Bar/Bar/Forms/FormImplementer.resx | 120 +++++++++ Bar/Bar/Forms/FormImplementers.Designer.cs | 136 ++++++++++ Bar/Bar/Forms/FormImplementers.cs | 111 ++++++++ Bar/Bar/Forms/FormImplementers.resx | 120 +++++++++ Bar/Bar/Program.cs | 10 +- .../BusinessLogics/ImplementerLogic.cs | 135 ++++++++++ .../BusinessLogics/OrderLogic.cs | 24 ++ .../BusinessLogics/WorkModeling.cs | 153 +++++++++++ .../BindingModels/CocktailBindingModel.cs | 2 +- .../BindingModels/ImplementerBindingModel.cs | 17 ++ .../BindingModels/OrderBindingModel.cs | 1 + .../BindingModels/ReportBindingModel.cs | 4 +- .../IImplementerLogic.cs | 19 ++ .../BusinessLogicContracts/IOrderLogic.cs | 1 + .../BusinessLogicContracts/IWorkProcess.cs | 9 + .../SearchModels/ComponentSearchModel.cs | 3 +- .../SearchModels/ImplementerSearchModel.cs | 11 + .../SearchModels/OrderSearchModel.cs | 11 +- .../StoragesContracts/IImplementerStorage.cs | 21 ++ .../ViewModels/CocktailViewModel.cs | 6 +- .../ViewModels/ComponentViewModel.cs | 6 +- .../ViewModels/ImplementerViewModel.cs | 22 ++ .../BarContracts/ViewModels/OrderViewModel.cs | 22 +- .../ReportCocktailComponentViewModel.cs | 11 + .../ViewModels/ReportOrdersViewModel.cs | 8 +- .../BarDataModels/Models/IImplementerModel.cs | 13 + .../BarDatabaseImplement/BarDatabase.cs | 2 + .../Implements/ImplementerStorage.cs | 90 +++++++ .../Implements/OrderStorage.cs | 20 +- .../Migrations/20240621140852_2.Designer.cs | 254 ++++++++++++++++++ .../Migrations/20240621140852_2.cs | 65 +++++ .../Migrations/BarDatabaseModelSnapshot.cs | 41 +++ .../Models/Implementer.cs | 64 +++++ .../BarDatabaseImplement/Models/Order.cs | 9 +- .../Controllers/ImplementerController.cs | 108 ++++++++ 39 files changed, 1939 insertions(+), 36 deletions(-) create mode 100644 Bar/Bar/Forms/FormImplementer.Designer.cs create mode 100644 Bar/Bar/Forms/FormImplementer.cs create mode 100644 Bar/Bar/Forms/FormImplementer.resx create mode 100644 Bar/Bar/Forms/FormImplementers.Designer.cs create mode 100644 Bar/Bar/Forms/FormImplementers.cs create mode 100644 Bar/Bar/Forms/FormImplementers.resx create mode 100644 Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/ImplementerLogic.cs create mode 100644 Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/WorkModeling.cs create mode 100644 Bar/BarContracts/BarContracts/BindingModels/ImplementerBindingModel.cs create mode 100644 Bar/BarContracts/BarContracts/BusinessLogicContracts/IImplementerLogic.cs create mode 100644 Bar/BarContracts/BarContracts/BusinessLogicContracts/IWorkProcess.cs create mode 100644 Bar/BarContracts/BarContracts/SearchModels/ImplementerSearchModel.cs create mode 100644 Bar/BarContracts/BarContracts/StoragesContracts/IImplementerStorage.cs create mode 100644 Bar/BarContracts/BarContracts/ViewModels/ImplementerViewModel.cs create mode 100644 Bar/BarContracts/BarContracts/ViewModels/ReportCocktailComponentViewModel.cs create mode 100644 Bar/BarDataModels/BarDataModels/Models/IImplementerModel.cs create mode 100644 Bar/BarDatabaseImplement/BarDatabaseImplement/Implements/ImplementerStorage.cs create mode 100644 Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/20240621140852_2.Designer.cs create mode 100644 Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/20240621140852_2.cs create mode 100644 Bar/BarDatabaseImplement/BarDatabaseImplement/Models/Implementer.cs create mode 100644 Bar/BarRestApi/Controllers/ImplementerController.cs diff --git a/Bar/Bar/FormMain.Designer.cs b/Bar/Bar/FormMain.Designer.cs index ed53c73..c34cc30 100644 --- a/Bar/Bar/FormMain.Designer.cs +++ b/Bar/Bar/FormMain.Designer.cs @@ -39,10 +39,12 @@ this.ComponentsStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.CocktailStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ClientsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.EmployersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.отчётыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.списокКомпонентовToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.компонентыПоИзделиямToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.списокЗаказовToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.запускРаботToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.DataGridView)).BeginInit(); this.menuStrip1.SuspendLayout(); this.SuspendLayout(); @@ -112,7 +114,8 @@ this.menuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.ToolStripMenu, - this.отчётыToolStripMenuItem}); + this.отчётыToolStripMenuItem, + this.запускРаботToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Size = new System.Drawing.Size(1279, 28); @@ -124,7 +127,8 @@ this.ToolStripMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.ComponentsStripMenuItem, this.CocktailStripMenuItem, - this.ClientsToolStripMenuItem}); + this.ClientsToolStripMenuItem, + this.EmployersToolStripMenuItem}); this.ToolStripMenu.Name = "ToolStripMenu"; this.ToolStripMenu.Size = new System.Drawing.Size(117, 24); this.ToolStripMenu.Text = "Справочники"; @@ -150,6 +154,13 @@ this.ClientsToolStripMenuItem.Text = "Клиенты"; this.ClientsToolStripMenuItem.Click += new System.EventHandler(this.ClientsToolStripMenuItem_Click); // + // EmployersToolStripMenuItem + // + this.EmployersToolStripMenuItem.Name = "EmployersToolStripMenuItem"; + this.EmployersToolStripMenuItem.Size = new System.Drawing.Size(224, 26); + this.EmployersToolStripMenuItem.Text = "Исполнители"; + this.EmployersToolStripMenuItem.Click += new System.EventHandler(this.EmployersToolStripMenuItem_Click); + // // отчётыToolStripMenuItem // this.отчётыToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -181,6 +192,13 @@ this.списокЗаказовToolStripMenuItem.Text = "Список заказов"; this.списокЗаказовToolStripMenuItem.Click += new System.EventHandler(this.OrdersToolStripMenuItem_Click); // + // запускРаботToolStripMenuItem + // + this.запускРаботToolStripMenuItem.Name = "запускРаботToolStripMenuItem"; + this.запускРаботToolStripMenuItem.Size = new System.Drawing.Size(114, 24); + this.запускРаботToolStripMenuItem.Text = "Запуск работ"; + this.запускРаботToolStripMenuItem.Click += new System.EventHandler(this.запускРаботToolStripMenuItem_Click); + // // FormMain // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); @@ -221,5 +239,7 @@ private ToolStripMenuItem компонентыПоИзделиямToolStripMenuItem; private ToolStripMenuItem списокЗаказовToolStripMenuItem; private ToolStripMenuItem ClientsToolStripMenuItem; + private ToolStripMenuItem запускРаботToolStripMenuItem; + private ToolStripMenuItem EmployersToolStripMenuItem; } } \ No newline at end of file diff --git a/Bar/Bar/FormMain.cs b/Bar/Bar/FormMain.cs index d48c628..9024738 100644 --- a/Bar/Bar/FormMain.cs +++ b/Bar/Bar/FormMain.cs @@ -1,5 +1,6 @@ using BarContracts.BindingModels; using BarContracts.BusinessLogicContracts; +using BarContracts.BusinessLogicsContracts; using BarView.Forms; using Microsoft.Extensions.Logging; @@ -10,13 +11,15 @@ namespace BarView private readonly ILogger _logger; private readonly IOrderLogic _orderLogic; private readonly IReportLogic _reportLogic; - public FormMain(ILogger Logger, IOrderLogic OrderLogic, IReportLogic ReportLogic) + private readonly IWorkProcess _workProcess; + public FormMain(ILogger Logger, IOrderLogic OrderLogic, IReportLogic ReportLogic, IWorkProcess WorkProcess) { InitializeComponent(); _logger = Logger; _orderLogic = OrderLogic; _reportLogic = ReportLogic; + _workProcess = WorkProcess; } private void FormMain_Load(object sender, EventArgs e) @@ -37,6 +40,7 @@ namespace BarView DataGridView.DataSource = List; DataGridView.Columns["CocktailId"].Visible = false; DataGridView.Columns["ClientId"].Visible = false; + DataGridView.Columns["ImplementerId"].Visible = false; DataGridView.Columns["CocktailName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; } @@ -207,5 +211,23 @@ namespace BarView Form.ShowDialog(); } } + + private void запускРаботToolStripMenuItem_Click(object sender, EventArgs e) + { + var ImplementerLogic = Program.ServiceProvider?.GetService(typeof(IImplementerLogic)); + _workProcess.DoWork((ImplementerLogic as IImplementerLogic)!, _orderLogic); + + MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void EmployersToolStripMenuItem_Click(object sender, EventArgs e) + { + var Service = Program.ServiceProvider?.GetService(typeof(FormImplementers)); + + if (Service is FormImplementers Form) + { + Form.ShowDialog(); + } + } } } diff --git a/Bar/Bar/Forms/FormImplementer.Designer.cs b/Bar/Bar/Forms/FormImplementer.Designer.cs new file mode 100644 index 0000000..5b84b57 --- /dev/null +++ b/Bar/Bar/Forms/FormImplementer.Designer.cs @@ -0,0 +1,173 @@ +namespace BarView.Forms +{ + partial class FormImplementer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + FioTextBox = new TextBox(); + FioLabel = new Label(); + PasswordTextBox = new TextBox(); + PasswordLabel = new Label(); + WorkExperienceLabel = new Label(); + WorkExperienceNumericUpDown = new NumericUpDown(); + QualificationNumericUpDown = new NumericUpDown(); + QualificationLabel = new Label(); + CancelButton = new Button(); + SaveButton = new Button(); + ((System.ComponentModel.ISupportInitialize)WorkExperienceNumericUpDown).BeginInit(); + ((System.ComponentModel.ISupportInitialize)QualificationNumericUpDown).BeginInit(); + SuspendLayout(); + // + // FioTextBox + // + FioTextBox.Location = new Point(137, 9); + FioTextBox.Margin = new Padding(3, 2, 3, 2); + FioTextBox.Name = "FioTextBox"; + FioTextBox.Size = new Size(335, 23); + FioTextBox.TabIndex = 3; + // + // FioLabel + // + FioLabel.AutoSize = true; + FioLabel.Location = new Point(10, 12); + FioLabel.Name = "FioLabel"; + FioLabel.Size = new Size(112, 15); + FioLabel.TabIndex = 2; + FioLabel.Text = "ФИО исполнителя:"; + // + // PasswordTextBox + // + PasswordTextBox.Location = new Point(137, 40); + PasswordTextBox.Margin = new Padding(3, 2, 3, 2); + PasswordTextBox.Name = "PasswordTextBox"; + PasswordTextBox.Size = new Size(335, 23); + PasswordTextBox.TabIndex = 5; + // + // PasswordLabel + // + PasswordLabel.AutoSize = true; + PasswordLabel.Location = new Point(10, 43); + PasswordLabel.Name = "PasswordLabel"; + PasswordLabel.Size = new Size(52, 15); + PasswordLabel.TabIndex = 4; + PasswordLabel.Text = "Пароль:"; + // + // WorkExperienceLabel + // + WorkExperienceLabel.AutoSize = true; + WorkExperienceLabel.Location = new Point(10, 75); + WorkExperienceLabel.Name = "WorkExperienceLabel"; + WorkExperienceLabel.Size = new Size(84, 15); + WorkExperienceLabel.TabIndex = 6; + WorkExperienceLabel.Text = "Опыт работы:"; + // + // WorkExperienceNumericUpDown + // + WorkExperienceNumericUpDown.Location = new Point(137, 73); + WorkExperienceNumericUpDown.Margin = new Padding(3, 2, 3, 2); + WorkExperienceNumericUpDown.Name = "WorkExperienceNumericUpDown"; + WorkExperienceNumericUpDown.Size = new Size(108, 23); + WorkExperienceNumericUpDown.TabIndex = 8; + // + // QualificationNumericUpDown + // + QualificationNumericUpDown.Location = new Point(137, 106); + QualificationNumericUpDown.Margin = new Padding(3, 2, 3, 2); + QualificationNumericUpDown.Name = "QualificationNumericUpDown"; + QualificationNumericUpDown.Size = new Size(108, 23); + QualificationNumericUpDown.TabIndex = 10; + // + // QualificationLabel + // + QualificationLabel.AutoSize = true; + QualificationLabel.Location = new Point(10, 108); + QualificationLabel.Name = "QualificationLabel"; + QualificationLabel.Size = new Size(91, 15); + QualificationLabel.TabIndex = 9; + QualificationLabel.Text = "Квалификация:"; + // + // CancelButton + // + CancelButton.Location = new Point(353, 142); + CancelButton.Margin = new Padding(3, 2, 3, 2); + CancelButton.Name = "CancelButton"; + CancelButton.Size = new Size(119, 30); + CancelButton.TabIndex = 12; + CancelButton.Text = "Отмена"; + CancelButton.UseVisualStyleBackColor = true; + CancelButton.Click += CancelButton_Click; + // + // SaveButton + // + SaveButton.Location = new Point(233, 142); + SaveButton.Margin = new Padding(3, 2, 3, 2); + SaveButton.Name = "SaveButton"; + SaveButton.Size = new Size(114, 30); + SaveButton.TabIndex = 11; + SaveButton.Text = "Сохранить"; + SaveButton.UseVisualStyleBackColor = true; + SaveButton.Click += SaveButton_Click; + // + // FormImplementer + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(482, 183); + Controls.Add(CancelButton); + Controls.Add(SaveButton); + Controls.Add(QualificationNumericUpDown); + Controls.Add(QualificationLabel); + Controls.Add(WorkExperienceNumericUpDown); + Controls.Add(WorkExperienceLabel); + Controls.Add(PasswordTextBox); + Controls.Add(PasswordLabel); + Controls.Add(FioTextBox); + Controls.Add(FioLabel); + Margin = new Padding(3, 2, 3, 2); + Name = "FormImplementer"; + Text = "Исполнитель"; + Load += FormImplementer_Load; + ((System.ComponentModel.ISupportInitialize)WorkExperienceNumericUpDown).EndInit(); + ((System.ComponentModel.ISupportInitialize)QualificationNumericUpDown).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private TextBox FioTextBox; + private Label FioLabel; + private TextBox PasswordTextBox; + private Label PasswordLabel; + private Label WorkExperienceLabel; + private NumericUpDown WorkExperienceNumericUpDown; + private NumericUpDown QualificationNumericUpDown; + private Label QualificationLabel; + private Button CancelButton; + private Button SaveButton; + } +} \ No newline at end of file diff --git a/Bar/Bar/Forms/FormImplementer.cs b/Bar/Bar/Forms/FormImplementer.cs new file mode 100644 index 0000000..0671882 --- /dev/null +++ b/Bar/Bar/Forms/FormImplementer.cs @@ -0,0 +1,105 @@ +using BarContracts.BindingModels; +using BarContracts.BusinessLogicsContracts; +using BarContracts.SearchModels; +using Microsoft.Extensions.Logging; + +namespace BarView.Forms +{ + public partial class FormImplementer : Form + { + private readonly ILogger _logger; + private readonly IImplementerLogic _logic; + + private int? _id; + + public int Id { set { _id = value; } } + + public FormImplementer(ILogger Logger, IImplementerLogic Logic) + { + InitializeComponent(); + + _logger = Logger; + _logic = Logic; + } + + private void FormImplementer_Load(object sender, EventArgs e) + { + if (_id.HasValue) + { + try + { + _logger.LogInformation("Получение исполнителя"); + + var View = _logic.ReadElement(new ImplementerSearchModel + { + Id = _id.Value + }); + + if (View != null) + { + FioTextBox.Text = View.ImplementerFIO; + PasswordTextBox.Text = View.Password; + WorkExperienceNumericUpDown.Value = View.WorkExperience; + QualificationNumericUpDown.Value = View.Qualification; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения исполнителя"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void SaveButton_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(FioTextBox.Text)) + { + MessageBox.Show("Заполните ФИО", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (string.IsNullOrEmpty(PasswordTextBox.Text)) + { + MessageBox.Show("Заполните пароль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + _logger.LogInformation("Сохранение исполнителя"); + + try + { + var Model = new ImplementerBindingModel + { + Id = _id ?? 0, + ImplementerFIO = FioTextBox.Text, + Password = PasswordTextBox.Text, + WorkExperience = (int)WorkExperienceNumericUpDown.Value, + Qualification = (int)QualificationNumericUpDown.Value + }; + + var OperationResult = _id.HasValue ? _logic.Update(Model) : _logic.Create(Model); + if (!OperationResult) + { + throw new Exception("Ошибка при создании или обновлении. Дополнительная информация в логах."); + } + + MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + + DialogResult = DialogResult.OK; + Close(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка сохранения исполнителя"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void CancelButton_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/Bar/Bar/Forms/FormImplementer.resx b/Bar/Bar/Forms/FormImplementer.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/Bar/Bar/Forms/FormImplementer.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Bar/Bar/Forms/FormImplementers.Designer.cs b/Bar/Bar/Forms/FormImplementers.Designer.cs new file mode 100644 index 0000000..f9e7418 --- /dev/null +++ b/Bar/Bar/Forms/FormImplementers.Designer.cs @@ -0,0 +1,136 @@ +namespace BarView.Forms +{ + partial class FormImplementers + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + ToolsPanel = new Panel(); + RefreshButton = new Button(); + DeleteButton = new Button(); + UpdateButton = new Button(); + AddButton = new Button(); + DataGridView = new DataGridView(); + ToolsPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)DataGridView).BeginInit(); + SuspendLayout(); + // + // ToolsPanel + // + ToolsPanel.Controls.Add(RefreshButton); + ToolsPanel.Controls.Add(DeleteButton); + ToolsPanel.Controls.Add(UpdateButton); + ToolsPanel.Controls.Add(AddButton); + ToolsPanel.Location = new Point(532, 9); + ToolsPanel.Margin = new Padding(3, 2, 3, 2); + ToolsPanel.Name = "ToolsPanel"; + ToolsPanel.Size = new Size(116, 320); + ToolsPanel.TabIndex = 3; + // + // RefreshButton + // + RefreshButton.Location = new Point(3, 126); + RefreshButton.Margin = new Padding(3, 2, 3, 2); + RefreshButton.Name = "RefreshButton"; + RefreshButton.Size = new Size(110, 27); + RefreshButton.TabIndex = 3; + RefreshButton.Text = "Обновить"; + RefreshButton.UseVisualStyleBackColor = true; + RefreshButton.Click += RefreshButton_Click; + // + // DeleteButton + // + DeleteButton.Location = new Point(3, 84); + DeleteButton.Margin = new Padding(3, 2, 3, 2); + DeleteButton.Name = "DeleteButton"; + DeleteButton.Size = new Size(110, 27); + DeleteButton.TabIndex = 2; + DeleteButton.Text = "Удалить"; + DeleteButton.UseVisualStyleBackColor = true; + DeleteButton.Click += DeleteButton_Click; + // + // UpdateButton + // + UpdateButton.Location = new Point(3, 42); + UpdateButton.Margin = new Padding(3, 2, 3, 2); + UpdateButton.Name = "UpdateButton"; + UpdateButton.Size = new Size(110, 27); + UpdateButton.TabIndex = 1; + UpdateButton.Text = "Изменить"; + UpdateButton.UseVisualStyleBackColor = true; + UpdateButton.Click += UpdateButton_Click; + // + // AddButton + // + AddButton.Location = new Point(3, 2); + AddButton.Margin = new Padding(3, 2, 3, 2); + AddButton.Name = "AddButton"; + AddButton.Size = new Size(110, 27); + AddButton.TabIndex = 0; + AddButton.Text = "Добавить"; + AddButton.UseVisualStyleBackColor = true; + AddButton.Click += AddButton_Click; + // + // DataGridView + // + DataGridView.AllowUserToAddRows = false; + DataGridView.AllowUserToDeleteRows = false; + DataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; + DataGridView.Location = new Point(10, 9); + DataGridView.Margin = new Padding(3, 2, 3, 2); + DataGridView.Name = "DataGridView"; + DataGridView.ReadOnly = true; + DataGridView.RowHeadersWidth = 51; + DataGridView.RowTemplate.Height = 29; + DataGridView.Size = new Size(516, 320); + DataGridView.TabIndex = 2; + // + // FormImplementers + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(653, 338); + Controls.Add(ToolsPanel); + Controls.Add(DataGridView); + Margin = new Padding(3, 2, 3, 2); + Name = "FormImplementers"; + Text = "Исполнители"; + Load += FormImplementers_Load; + ToolsPanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)DataGridView).EndInit(); + ResumeLayout(false); + } + + #endregion + + private Panel ToolsPanel; + private Button RefreshButton; + private Button DeleteButton; + private Button UpdateButton; + private Button AddButton; + private DataGridView DataGridView; + } +} \ No newline at end of file diff --git a/Bar/Bar/Forms/FormImplementers.cs b/Bar/Bar/Forms/FormImplementers.cs new file mode 100644 index 0000000..ecb8f33 --- /dev/null +++ b/Bar/Bar/Forms/FormImplementers.cs @@ -0,0 +1,111 @@ +using BarContracts.BindingModels; +using BarContracts.BusinessLogicsContracts; +using Microsoft.Extensions.Logging; + +namespace BarView.Forms +{ + public partial class FormImplementers : Form + { + private readonly ILogger _logger; + private readonly IImplementerLogic _implementerLogic; + + public FormImplementers(ILogger Logger, IImplementerLogic ImplementerLogic) + { + InitializeComponent(); + + _logger = Logger; + _implementerLogic = ImplementerLogic; + } + + private void LoadData() + { + try + { + var List = _implementerLogic.ReadList(null); + + if (List != null) + { + DataGridView.DataSource = List; + DataGridView.Columns["Id"].Visible = false; + DataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + } + + _logger.LogInformation("Загрузка исполнителей"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки исполнителей"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void FormImplementers_Load(object sender, EventArgs e) + { + LoadData(); + } + + private void AddButton_Click(object sender, EventArgs e) + { + var Service = Program.ServiceProvider?.GetService(typeof(FormImplementer)); + + if (Service is FormImplementer Form) + { + if (Form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } + + private void UpdateButton_Click(object sender, EventArgs e) + { + if (DataGridView.SelectedRows.Count == 1) + { + var service = Program.ServiceProvider?.GetService(typeof(FormImplementer)); + if (service is FormImplementer Form) + { + Form.Id = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value); + if (Form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } + } + + private void DeleteButton_Click(object sender, EventArgs e) + { + if (DataGridView.SelectedRows.Count == 1) + { + if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + int Id = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Удаление исполнителя"); + + try + { + if (!_implementerLogic.Delete(new ImplementerBindingModel + { + Id = Id + })) + { + throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); + } + + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка удаления исполнителя"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } + + private void RefreshButton_Click(object sender, EventArgs e) + { + LoadData(); + } + } +} diff --git a/Bar/Bar/Forms/FormImplementers.resx b/Bar/Bar/Forms/FormImplementers.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/Bar/Bar/Forms/FormImplementers.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Bar/Bar/Program.cs b/Bar/Bar/Program.cs index cf102f0..80010d0 100644 --- a/Bar/Bar/Program.cs +++ b/Bar/Bar/Program.cs @@ -8,6 +8,8 @@ using BarView.Forms; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NLog.Extensions.Logging; +using BarContracts.BusinessLogicsContracts; +using BarContracts.BusinessLogicContracts; namespace BarView @@ -41,12 +43,16 @@ namespace BarView Services.AddTransient(); Services.AddTransient(); + Services.AddTransient(); + Services.AddTransient(); + Services.AddTransient(); Services.AddTransient(); Services.AddTransient(); Services.AddTransient(); Services.AddTransient(); - Services.AddTransient(); + Services.AddTransient(); + Services.AddTransient(); Services.AddTransient(); Services.AddTransient(); @@ -62,6 +68,8 @@ namespace BarView Services.AddTransient(); Services.AddTransient(); Services.AddTransient(); + Services.AddTransient(); + Services.AddTransient(); } } } \ No newline at end of file diff --git a/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/ImplementerLogic.cs b/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/ImplementerLogic.cs new file mode 100644 index 0000000..4748789 --- /dev/null +++ b/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/ImplementerLogic.cs @@ -0,0 +1,135 @@ +using BarContracts.BindingModels; +using BarContracts.BusinessLogicsContracts; +using BarContracts.SearchModels; +using BarContracts.StoragesContracts; +using BarContracts.ViewModels; +using Microsoft.Extensions.Logging; + +namespace BarBusinessLogic.BusinessLogics +{ + public class ImplementerLogic : IImplementerLogic + { + private readonly ILogger _logger; + private readonly IImplementerStorage _implementerStorage; + + public ImplementerLogic(ILogger Logger, IImplementerStorage ImplementerStorage) + { + _logger = Logger; + _implementerStorage = ImplementerStorage; + } + + public List? ReadList(ImplementerSearchModel? Model) + { + _logger.LogInformation("ReadList. ImplementerFIO: {ImplementerFIO}. Password: {Password}. Id: {Id}", + Model?.ImplementerFIO, Model?.Password?.Length, Model?.Id); + + var List = Model == null ? _implementerStorage.GetFullList() : _implementerStorage.GetFilteredList(Model); + + if (List == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + + _logger.LogInformation("ReadList. Count: {Count}", List.Count); + return List; + } + + public ImplementerViewModel? ReadElement(ImplementerSearchModel Model) + { + if (Model is null) + { + throw new ArgumentNullException(nameof(Model)); + } + + _logger.LogInformation("ReadElement. ImplementerFIO: {ImplementerFIO}. Password: {Password}. Id: {Id}", + Model?.ImplementerFIO, Model?.Password?.Length, Model?.Id); + + var Element = _implementerStorage.GetElement(Model); + + if (Element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + + _logger.LogInformation("ReadElement find. Id: {Id}", Element.Id); + return Element; + } + + public bool Create(ImplementerBindingModel Model) + { + CheckModel(Model); + + if (_implementerStorage.Insert(Model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + + return true; + } + + public bool Update(ImplementerBindingModel Model) + { + CheckModel(Model); + + if (_implementerStorage.Update(Model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + + return true; + } + + public bool Delete(ImplementerBindingModel Model) + { + CheckModel(Model, false); + + _logger.LogInformation("Delete. Id:{Id}", Model.Id); + + if (_implementerStorage.Delete(Model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + + return true; + } + + private void CheckModel(ImplementerBindingModel Model, bool WithParams = true) + { + if (Model == null) + throw new ArgumentNullException(nameof(Model)); + + if (!WithParams) + return; + + if (string.IsNullOrEmpty(Model.ImplementerFIO)) + throw new ArgumentNullException("Нет ФИО исполнителя", nameof(Model.ImplementerFIO)); + + if (string.IsNullOrEmpty(Model.Password)) + throw new ArgumentNullException("Нет пароля исполнителя", nameof(Model.Password)); + + if (Model.WorkExperience < 0) + throw new ArgumentNullException("Стаж должен быть неотрицательным целым числом", nameof(Model.WorkExperience)); + + if (Model.Qualification < 0) + throw new ArgumentNullException("Квалификация должна быть неотрицательным целым числом", nameof(Model.Qualification)); + + _logger.LogInformation("Implementer. ImplementerFIO: {ImplementerFIO}. Password: {Password}. WorkExperience: {WorkExperience}. Qualification: {Qualification}. Id: {Id}", + Model.ImplementerFIO, Model.Password, Model.WorkExperience, Model.Qualification, Model.Id); + + var Implementer = _implementerStorage.GetElement(new ImplementerSearchModel + { + ImplementerFIO = Model.ImplementerFIO + }); + + if (Implementer != null && Implementer.Id != Model.Id) + { + throw new InvalidOperationException("Исполнитель с таким ФИО уже есть"); + } + } + } +} diff --git a/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/OrderLogic.cs b/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/OrderLogic.cs index 3084219..08f6c58 100644 --- a/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/OrderLogic.cs @@ -76,6 +76,8 @@ namespace BarBusinessLogic.BusinessLogics } Model.CocktailId = Order.CocktailId; + Model.ClientId = Order.ClientId; + if (!Model.ImplementerId.HasValue) Model.ImplementerId = Order.ImplementerId; Model.Count = Order.Count; Model.Sum = Order.Sum; Model.DateCreate = Order.DateCreate; @@ -129,5 +131,27 @@ namespace BarBusinessLogic.BusinessLogics Model.CocktailId, Model.Count, Model.Sum, Model.Status, Model.DateCreate, Model.DateImplement, Model.Id); } + + public OrderViewModel? ReadElement(OrderSearchModel Model) + { + if (Model == null) + { + throw new ArgumentNullException(nameof(Model)); + } + + _logger.LogInformation("ReadElement. ClientId: {ClientId}. Status: {Status}. ImplementerId: {ImplementerId}. DateFrom: {DateFrom}. DateTo: {DateTo}. OrderId: {Id}", + Model.ClientId, Model.Status, Model.ImplementerId, Model.DateFrom, Model.DateTo, Model.Id); + + var Order = _orderStorage.GetElement(Model); + + if (Order == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + + _logger.LogInformation("ReadElement find. Id: {Id}", Order.Id); + return Order; + } } } diff --git a/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/WorkModeling.cs b/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/WorkModeling.cs new file mode 100644 index 0000000..55657bd --- /dev/null +++ b/Bar/BarBusinessLogic/BarBusinessLogic/BusinessLogics/WorkModeling.cs @@ -0,0 +1,153 @@ +using BarContracts.BindingModels; +using BarContracts.BusinessLogicContracts; +using BarContracts.BusinessLogicsContracts; +using BarContracts.SearchModels; +using BarContracts.ViewModels; +using BarDataModels.Enums; +using Microsoft.Extensions.Logging; + +namespace BarBusinessLogic.BusinessLogics +{ + public class WorkModeling : IWorkProcess + { + private readonly ILogger _logger; + + private readonly Random _rnd; + + private IOrderLogic? _orderLogic; + + public WorkModeling(ILogger Logger) + { + _logger = Logger; + _rnd = new Random(1000); + } + + public void DoWork(IImplementerLogic ImplementerLogic, IOrderLogic OrderLogic) + { + _orderLogic = OrderLogic; + + var Implementers = ImplementerLogic.ReadList(null); + + if (Implementers == null) + { + _logger.LogWarning("DoWork. Implementers is null"); + return; + } + + var Orders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Accepted }); + var BeingProcessedOrders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.BeingProcessed }); + // in case there are BeingProcessed orders but no Accepted orders + + if (Orders == null || BeingProcessedOrders == null || (Orders.Count == 0 && BeingProcessedOrders.Count == 0)) + { + _logger.LogWarning("DoWork. Orders is null or empty"); + return; + } + + _logger.LogDebug("DoWork for {Count} orders", Orders.Count); + + foreach (var Implementer in Implementers) + { + Task.Run(() => WorkerWorkAsync(Implementer, Orders)); + } + } + + private async Task WorkerWorkAsync(ImplementerViewModel Implementer, List Orders) + { + if (_orderLogic == null || Implementer == null) + { + return; + } + + await RunOrderInWork(Implementer); + + await Task.Run(() => + { + foreach (var Order in Orders) + { + try + { + _logger.LogDebug("WorkerWorkAsync. Worker {Id} try get order {Order}", Implementer.Id, Order.Id); + + // TakeOrderInWork will fail when the worker tries to change status to BeingProcessed when the order is already BeingProcessed + // which would happen when other worker already acquired that order + bool AcquireResult = _orderLogic.TakeOrderInWork(new OrderBindingModel + { + Id = Order.Id, + ImplementerId = Implementer.Id + }); + + if (!AcquireResult) + { + _logger.LogDebug("WorkerWorkAsync. Worker {Id} tried to get order {Order} but it's already acquired by other worker", Implementer.Id, Order.Id); + continue; + } + + Thread.Sleep(Implementer.WorkExperience * _rnd.Next(100, 1000) * Order.Count); + + _logger.LogDebug("WorkerWorkAsync. Worker {Id} finish order {Order}", Implementer.Id, Order.Id); + _orderLogic.FinishOrder(new OrderBindingModel + { + Id = Order.Id + }); + } + + catch (InvalidOperationException ex) + { + _logger.LogWarning(ex, "Error try get work"); + } + + catch (Exception ex) + { + _logger.LogError(ex, "Error while do work"); + throw; + } + + Thread.Sleep(Implementer.Qualification * _rnd.Next(10, 100)); + } + }); + } + + private async Task RunOrderInWork(ImplementerViewModel Implementer) + { + if (_orderLogic == null || Implementer == null) + return; + + try + { + var RunOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel + { + ImplementerId = Implementer.Id, + Status = OrderStatus.BeingProcessed + })); + + if (RunOrder == null) + { + return; + } + + _logger.LogDebug("RunOrderInWork. Worker {Id} back to order {Order}", Implementer.Id, RunOrder.Id); + Thread.Sleep(Implementer.WorkExperience * _rnd.Next(100, 300) * RunOrder.Count); + + _logger.LogDebug("RunOrderInWork. Worker {Id} finish order {Order}", Implementer.Id, RunOrder.Id); + _orderLogic.FinishOrder(new OrderBindingModel + { + Id = RunOrder.Id + }); + + Thread.Sleep(Implementer.Qualification * _rnd.Next(10, 100)); + } + + catch (InvalidOperationException ex) + { + _logger.LogWarning(ex, "Error try get work"); + } + + catch (Exception ex) + { + _logger.LogError(ex, "Error while do work"); + throw; + } + } + } +} diff --git a/Bar/BarContracts/BarContracts/BindingModels/CocktailBindingModel.cs b/Bar/BarContracts/BarContracts/BindingModels/CocktailBindingModel.cs index b5cfd74..0a264cc 100644 --- a/Bar/BarContracts/BarContracts/BindingModels/CocktailBindingModel.cs +++ b/Bar/BarContracts/BarContracts/BindingModels/CocktailBindingModel.cs @@ -2,7 +2,7 @@ namespace BarContracts.BindingModels { - public class CocktailBindingModel : ICocktailModel + public class CocktailBindingModel : ICocktailModel { public int Id { get; set; } public string CocktailName { get; set; } = string.Empty; diff --git a/Bar/BarContracts/BarContracts/BindingModels/ImplementerBindingModel.cs b/Bar/BarContracts/BarContracts/BindingModels/ImplementerBindingModel.cs new file mode 100644 index 0000000..6a98839 --- /dev/null +++ b/Bar/BarContracts/BarContracts/BindingModels/ImplementerBindingModel.cs @@ -0,0 +1,17 @@ +using BarDataModels.Models; + +namespace BarContracts.BindingModels +{ + public class ImplementerBindingModel : IImplementerModel + { + public int Id { get; set; } + + public string ImplementerFIO { get; set; } = string.Empty; + + public string Password { get; set; } = string.Empty; + + public int WorkExperience { get; set; } + + public int Qualification { get; set; } + } +} diff --git a/Bar/BarContracts/BarContracts/BindingModels/OrderBindingModel.cs b/Bar/BarContracts/BarContracts/BindingModels/OrderBindingModel.cs index 92e0f44..bc52b9c 100644 --- a/Bar/BarContracts/BarContracts/BindingModels/OrderBindingModel.cs +++ b/Bar/BarContracts/BarContracts/BindingModels/OrderBindingModel.cs @@ -8,6 +8,7 @@ namespace BarContracts.BindingModels public int Id { get; set; } public int CocktailId { get; set; } public int ClientId { get; set; } + public int? ImplementerId { get; set; } public int Count { get; set; } public double Sum { get; set; } public OrderStatus Status { get; set; } = OrderStatus.Undefined; diff --git a/Bar/BarContracts/BarContracts/BindingModels/ReportBindingModel.cs b/Bar/BarContracts/BarContracts/BindingModels/ReportBindingModel.cs index 7d22f1b..cb9af38 100644 --- a/Bar/BarContracts/BarContracts/BindingModels/ReportBindingModel.cs +++ b/Bar/BarContracts/BarContracts/BindingModels/ReportBindingModel.cs @@ -3,9 +3,9 @@ public class ReportBindingModel { public string FileName { get; set; } = string.Empty; - + public DateTime? DateFrom { get; set; } - + public DateTime? DateTo { get; set; } } } diff --git a/Bar/BarContracts/BarContracts/BusinessLogicContracts/IImplementerLogic.cs b/Bar/BarContracts/BarContracts/BusinessLogicContracts/IImplementerLogic.cs new file mode 100644 index 0000000..172914b --- /dev/null +++ b/Bar/BarContracts/BarContracts/BusinessLogicContracts/IImplementerLogic.cs @@ -0,0 +1,19 @@ +using BarContracts.BindingModels; +using BarContracts.SearchModels; +using BarContracts.ViewModels; + +namespace BarContracts.BusinessLogicsContracts +{ + public interface IImplementerLogic + { + List? ReadList(ImplementerSearchModel? Model); + + ImplementerViewModel? ReadElement(ImplementerSearchModel Model); + + bool Create(ImplementerBindingModel Model); + + bool Update(ImplementerBindingModel Model); + + bool Delete(ImplementerBindingModel Model); + } +} diff --git a/Bar/BarContracts/BarContracts/BusinessLogicContracts/IOrderLogic.cs b/Bar/BarContracts/BarContracts/BusinessLogicContracts/IOrderLogic.cs index fc46c36..b9d185c 100644 --- a/Bar/BarContracts/BarContracts/BusinessLogicContracts/IOrderLogic.cs +++ b/Bar/BarContracts/BarContracts/BusinessLogicContracts/IOrderLogic.cs @@ -11,5 +11,6 @@ namespace BarContracts.BusinessLogicContracts bool TakeOrderInWork(OrderBindingModel Model); bool FinishOrder(OrderBindingModel Model); bool DeliveryOrder(OrderBindingModel Model); + OrderViewModel? ReadElement(OrderSearchModel Model); } } diff --git a/Bar/BarContracts/BarContracts/BusinessLogicContracts/IWorkProcess.cs b/Bar/BarContracts/BarContracts/BusinessLogicContracts/IWorkProcess.cs new file mode 100644 index 0000000..fc6e176 --- /dev/null +++ b/Bar/BarContracts/BarContracts/BusinessLogicContracts/IWorkProcess.cs @@ -0,0 +1,9 @@ +using BarContracts.BusinessLogicsContracts; + +namespace BarContracts.BusinessLogicContracts +{ + public interface IWorkProcess + { + void DoWork(IImplementerLogic ImplementerLogic, IOrderLogic OrderLogic); + } +} diff --git a/Bar/BarContracts/BarContracts/SearchModels/ComponentSearchModel.cs b/Bar/BarContracts/BarContracts/SearchModels/ComponentSearchModel.cs index 550c10c..23295f2 100644 --- a/Bar/BarContracts/BarContracts/SearchModels/ComponentSearchModel.cs +++ b/Bar/BarContracts/BarContracts/SearchModels/ComponentSearchModel.cs @@ -1,5 +1,4 @@ - -namespace BarContracts.SearchModels +namespace BarContracts.SearchModels { public class ComponentSearchModel { diff --git a/Bar/BarContracts/BarContracts/SearchModels/ImplementerSearchModel.cs b/Bar/BarContracts/BarContracts/SearchModels/ImplementerSearchModel.cs new file mode 100644 index 0000000..88112ec --- /dev/null +++ b/Bar/BarContracts/BarContracts/SearchModels/ImplementerSearchModel.cs @@ -0,0 +1,11 @@ +namespace BarContracts.SearchModels +{ + public class ImplementerSearchModel + { + public int? Id { get; set; } + + public string? ImplementerFIO { get; set; } + + public string? Password { get; set; } + } +} diff --git a/Bar/BarContracts/BarContracts/SearchModels/OrderSearchModel.cs b/Bar/BarContracts/BarContracts/SearchModels/OrderSearchModel.cs index 70949ab..73a3ec9 100644 --- a/Bar/BarContracts/BarContracts/SearchModels/OrderSearchModel.cs +++ b/Bar/BarContracts/BarContracts/SearchModels/OrderSearchModel.cs @@ -1,12 +1,19 @@ -namespace BarContracts.SearchModels +using BarDataModels.Enums; + +namespace BarContracts.SearchModels { public class OrderSearchModel { public int? Id { get; set; } + public int? ClientId { get; set; } - public DateTime? DateFrom { get; set; } + public OrderStatus? Status { get; set; } + public int? ImplementerId { get; set; } + + public DateTime? DateFrom { get; set; } + public DateTime? DateTo { get; set; } } } diff --git a/Bar/BarContracts/BarContracts/StoragesContracts/IImplementerStorage.cs b/Bar/BarContracts/BarContracts/StoragesContracts/IImplementerStorage.cs new file mode 100644 index 0000000..8df6fff --- /dev/null +++ b/Bar/BarContracts/BarContracts/StoragesContracts/IImplementerStorage.cs @@ -0,0 +1,21 @@ +using BarContracts.BindingModels; +using BarContracts.SearchModels; +using BarContracts.ViewModels; + +namespace BarContracts.StoragesContracts +{ + public interface IImplementerStorage + { + List GetFullList(); + + List GetFilteredList(ImplementerSearchModel Model); + + ImplementerViewModel? GetElement(ImplementerSearchModel Model); + + ImplementerViewModel? Insert(ImplementerBindingModel Model); + + ImplementerViewModel? Update(ImplementerBindingModel Model); + + ImplementerViewModel? Delete(ImplementerBindingModel Model); + } +} diff --git a/Bar/BarContracts/BarContracts/ViewModels/CocktailViewModel.cs b/Bar/BarContracts/BarContracts/ViewModels/CocktailViewModel.cs index be54117..4cc7e1b 100644 --- a/Bar/BarContracts/BarContracts/ViewModels/CocktailViewModel.cs +++ b/Bar/BarContracts/BarContracts/ViewModels/CocktailViewModel.cs @@ -7,12 +7,12 @@ namespace BarContracts.ViewModels { public int Id { get; set; } - [DisplayName("Название Коктейля")] + [DisplayName("Название Коктейльа")] public string CocktailName { get; set; } = string.Empty; - [DisplayName("Цена")] + [DisplayName("Цена")] public double Price { get; set; } - + public Dictionary CocktailComponents { get; diff --git a/Bar/BarContracts/BarContracts/ViewModels/ComponentViewModel.cs b/Bar/BarContracts/BarContracts/ViewModels/ComponentViewModel.cs index 24a45d3..2fc57e3 100644 --- a/Bar/BarContracts/BarContracts/ViewModels/ComponentViewModel.cs +++ b/Bar/BarContracts/BarContracts/ViewModels/ComponentViewModel.cs @@ -7,10 +7,10 @@ namespace BarContracts.ViewModels { public int Id { get; set; } - [DisplayName("Название компонента")] + [DisplayName("Название компонента")] public string ComponentName { get; set; } = string.Empty; - - [DisplayName("Цена")] + + [DisplayName("Цена")] public double Cost { get; set; } } } diff --git a/Bar/BarContracts/BarContracts/ViewModels/ImplementerViewModel.cs b/Bar/BarContracts/BarContracts/ViewModels/ImplementerViewModel.cs new file mode 100644 index 0000000..81302e3 --- /dev/null +++ b/Bar/BarContracts/BarContracts/ViewModels/ImplementerViewModel.cs @@ -0,0 +1,22 @@ +using BarDataModels.Models; +using System.ComponentModel; + +namespace BarContracts.ViewModels +{ + public class ImplementerViewModel : IImplementerModel + { + public int Id { get; set; } + + [DisplayName("ФИО исполнителя")] + public string ImplementerFIO { get; set; } = string.Empty; + + [DisplayName("Пароль")] + public string Password { get; set; } = string.Empty; + + [DisplayName("Стаж работы")] + public int WorkExperience { get; set; } + + [DisplayName("Квалификация")] + public int Qualification { get; set; } + } +} diff --git a/Bar/BarContracts/BarContracts/ViewModels/OrderViewModel.cs b/Bar/BarContracts/BarContracts/ViewModels/OrderViewModel.cs index 1c116aa..1bc8e7b 100644 --- a/Bar/BarContracts/BarContracts/ViewModels/OrderViewModel.cs +++ b/Bar/BarContracts/BarContracts/ViewModels/OrderViewModel.cs @@ -2,34 +2,40 @@ using BarDataModels.Models; using System.ComponentModel; - namespace BarContracts.ViewModels { public class OrderViewModel : IOrderModel { [DisplayName("Номер")] public int Id { get; set; } - + public int CocktailId { get; set; } [DisplayName("Коктейль")] public string CocktailName { get; set; } = string.Empty; - public int ClientId { get; set; } + public int ClientId { get; set; } + [DisplayName("Клиент")] public string ClientFIO { get; set; } = string.Empty; - [DisplayName("Количество")] - public int Count { get; set; } + public int? ImplementerId { get; set; } + + [DisplayName("Исполнитель")] + public string? ImplementerFIO { get; set; } + + [DisplayName("Количество")] + public int Count { get; set; } + [DisplayName("Сумма")] public double Sum { get; set; } - + [DisplayName("Статус")] public OrderStatus Status { get; set; } = OrderStatus.Undefined; - + [DisplayName("Дата создания")] public DateTime DateCreate { get; set; } = DateTime.Now; - + [DisplayName("Дата выполнения")] public DateTime? DateImplement { get; set; } } diff --git a/Bar/BarContracts/BarContracts/ViewModels/ReportCocktailComponentViewModel.cs b/Bar/BarContracts/BarContracts/ViewModels/ReportCocktailComponentViewModel.cs new file mode 100644 index 0000000..70259a2 --- /dev/null +++ b/Bar/BarContracts/BarContracts/ViewModels/ReportCocktailComponentViewModel.cs @@ -0,0 +1,11 @@ +namespace BarContracts.ViewModels +{ + public class ReportCocktailComponentViewModel + { + public string CocktailName { get; set; } = string.Empty; + + public int TotalCount { get; set; } + + public List<(string Component, int Count)> Components { get; set; } = new(); + } +} diff --git a/Bar/BarContracts/BarContracts/ViewModels/ReportOrdersViewModel.cs b/Bar/BarContracts/BarContracts/ViewModels/ReportOrdersViewModel.cs index 61d84b2..8dd44e1 100644 --- a/Bar/BarContracts/BarContracts/ViewModels/ReportOrdersViewModel.cs +++ b/Bar/BarContracts/BarContracts/ViewModels/ReportOrdersViewModel.cs @@ -3,13 +3,13 @@ public class ReportOrdersViewModel { public int Id { get; set; } - + public DateTime DateCreate { get; set; } - + public string CocktailName { get; set; } = string.Empty; - + public double Sum { get; set; } - + public string Status { get; set; } = string.Empty; } } diff --git a/Bar/BarDataModels/BarDataModels/Models/IImplementerModel.cs b/Bar/BarDataModels/BarDataModels/Models/IImplementerModel.cs new file mode 100644 index 0000000..c2ebced --- /dev/null +++ b/Bar/BarDataModels/BarDataModels/Models/IImplementerModel.cs @@ -0,0 +1,13 @@ +namespace BarDataModels.Models +{ + public interface IImplementerModel : IId + { + string ImplementerFIO { get; } + + string Password { get; } + + int WorkExperience { get; } + + int Qualification { get; } + } +} diff --git a/Bar/BarDatabaseImplement/BarDatabaseImplement/BarDatabase.cs b/Bar/BarDatabaseImplement/BarDatabaseImplement/BarDatabase.cs index dfc030e..07a403a 100644 --- a/Bar/BarDatabaseImplement/BarDatabaseImplement/BarDatabase.cs +++ b/Bar/BarDatabaseImplement/BarDatabaseImplement/BarDatabase.cs @@ -27,5 +27,7 @@ namespace BarDatabaseImplement public virtual DbSet Orders { set; get; } public virtual DbSet Clients { set; get; } + + public virtual DbSet Implementers { set; get; } } } diff --git a/Bar/BarDatabaseImplement/BarDatabaseImplement/Implements/ImplementerStorage.cs b/Bar/BarDatabaseImplement/BarDatabaseImplement/Implements/ImplementerStorage.cs new file mode 100644 index 0000000..a7828bb --- /dev/null +++ b/Bar/BarDatabaseImplement/BarDatabaseImplement/Implements/ImplementerStorage.cs @@ -0,0 +1,90 @@ +using BarContracts.BindingModels; +using BarContracts.SearchModels; +using BarContracts.StoragesContracts; +using BarContracts.ViewModels; +using BarDatabaseImplement.Models; + +namespace BarDatabaseImplement.Implements +{ + public class ImplementerStorage : IImplementerStorage + { + public List GetFullList() + { + using var Context = new BarDatabase(); + + return Context.Implementers.Select(x => x.GetViewModel).ToList(); + } + + public List GetFilteredList(ImplementerSearchModel Model) + { + if (string.IsNullOrEmpty(Model.ImplementerFIO)) + { + return new(); + } + using var Context = new BarDatabase(); + return Context.Implementers.Where(x => x.ImplementerFIO.Contains(Model.ImplementerFIO)).Select(x => x.GetViewModel).ToList(); + } + + public ImplementerViewModel? GetElement(ImplementerSearchModel Model) + { + if (string.IsNullOrEmpty(Model.ImplementerFIO) && !Model.Id.HasValue) + { + return null; + } + + using var Context = new BarDatabase(); + + return Context.Implementers.FirstOrDefault(x => + (!string.IsNullOrEmpty(Model.ImplementerFIO) && x.ImplementerFIO == Model.ImplementerFIO && (!string.IsNullOrEmpty(Model.Password) ? x.Password == Model.Password : true)) || + (Model.Id.HasValue && x.Id == Model.Id)) + ?.GetViewModel; + } + + public ImplementerViewModel? Insert(ImplementerBindingModel Model) + { + var NewImplementer = Implementer.Create(Model); + if (NewImplementer == null) + { + return null; + } + using var Context = new BarDatabase(); + + Context.Implementers.Add(NewImplementer); + Context.SaveChanges(); + + return NewImplementer.GetViewModel; + } + + public ImplementerViewModel? Update(ImplementerBindingModel Model) + { + using var Context = new BarDatabase(); + + var Implementer = Context.Implementers.FirstOrDefault(x => x.Id == Model.Id); + if (Implementer == null) + { + return null; + } + + Implementer.Update(Model); + Context.SaveChanges(); + + return Implementer.GetViewModel; + } + + public ImplementerViewModel? Delete(ImplementerBindingModel Model) + { + using var Context = new BarDatabase(); + + var Implementer = Context.Implementers.FirstOrDefault(rec => rec.Id == Model.Id); + if (Implementer == null) + { + return null; + } + + Context.Implementers.Remove(Implementer); + Context.SaveChanges(); + + return Implementer.GetViewModel; + } + } +} diff --git a/Bar/BarDatabaseImplement/BarDatabaseImplement/Implements/OrderStorage.cs b/Bar/BarDatabaseImplement/BarDatabaseImplement/Implements/OrderStorage.cs index fe12766..555886f 100644 --- a/Bar/BarDatabaseImplement/BarDatabaseImplement/Implements/OrderStorage.cs +++ b/Bar/BarDatabaseImplement/BarDatabaseImplement/Implements/OrderStorage.cs @@ -16,6 +16,7 @@ namespace BarDatabaseImplement.Implements return Context.Orders .Include(x => x.Cocktail) .Include(x => x.Client) + .Include(x => x.Implementer) .Select(x => x.GetViewModel) .ToList(); } @@ -29,6 +30,7 @@ namespace BarDatabaseImplement.Implements return Context.Orders .Include(x => x.Cocktail) .Include(x => x.Client) + .Include(x => x.Implementer) .Where(x => (x.DateCreate >= Model.DateFrom && x.DateCreate <= Model.DateTo) && (!Model.ClientId.HasValue || x.ClientId == Model.ClientId)) .Select(x => x.GetViewModel) .ToList(); @@ -37,14 +39,18 @@ namespace BarDatabaseImplement.Implements return Context.Orders .Include(x => x.Cocktail) .Include(x => x.Client) - .Where(x => (Model.Id.HasValue && x.Id == Model.Id) || (Model.ClientId.HasValue && x.ClientId == Model.ClientId)) + .Include(x => x.Implementer) + .Where(x => (Model.Id.HasValue && x.Id == Model.Id) + || (Model.ClientId.HasValue && x.ClientId == Model.ClientId) + || (Model.ImplementerId.HasValue && x.ImplementerId == Model.ImplementerId) + || (Model.Status.HasValue && x.Status == Model.Status)) .Select(x => x.GetViewModel) .ToList(); } public OrderViewModel? GetElement(OrderSearchModel Model) { - if (!Model.Id.HasValue) + if (!Model.Id.HasValue && !Model.ImplementerId.HasValue && !Model.Status.HasValue) return null; using var Context = new BarDatabase(); @@ -52,7 +58,9 @@ namespace BarDatabaseImplement.Implements return Context.Orders .Include(x => x.Cocktail) .Include(x => x.Client) - .FirstOrDefault(x => Model.Id.HasValue && x.Id == Model.Id)? + .Include(x => x.Implementer) + .FirstOrDefault(x => (Model.Id.HasValue && x.Id == Model.Id) + || (Model.ImplementerId.HasValue && Model.Status.HasValue && x.ImplementerId == Model.ImplementerId && x.Status == Model.Status))? .GetViewModel; } @@ -70,7 +78,7 @@ namespace BarDatabaseImplement.Implements Context.Orders.Add(NewOrder); Context.SaveChanges(); - return Context.Orders.Include(x => x.Cocktail).Include(x => x.Client).FirstOrDefault(x => x.Id == NewOrder.Id)?.GetViewModel; + return Context.Orders.Include(x => x.Cocktail).Include(x => x.Client).Include(x => x.Implementer).FirstOrDefault(x => x.Id == NewOrder.Id)?.GetViewModel; } public OrderViewModel? Update(OrderBindingModel Model) @@ -84,13 +92,13 @@ namespace BarDatabaseImplement.Implements Order.Update(Model); Context.SaveChanges(); - return Context.Orders.Include(x => x.Cocktail).Include(x => x.Client).FirstOrDefault(x => x.Id == Model.Id)?.GetViewModel; + return Context.Orders.Include(x => x.Cocktail).Include(x => x.Client).Include(x => x.Implementer).FirstOrDefault(x => x.Id == Model.Id)?.GetViewModel; } public OrderViewModel? Delete(OrderBindingModel Model) { using var Context = new BarDatabase(); - var Order = Context.Orders.Include(x => x.Cocktail).Include(x => x.Client).FirstOrDefault(rec => rec.Id == Model.Id); + var Order = Context.Orders.Include(x => x.Cocktail).Include(x => x.Client).Include(x => x.Implementer).FirstOrDefault(rec => rec.Id == Model.Id); if (Order == null) return null; diff --git a/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/20240621140852_2.Designer.cs b/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/20240621140852_2.Designer.cs new file mode 100644 index 0000000..20d6ebc --- /dev/null +++ b/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/20240621140852_2.Designer.cs @@ -0,0 +1,254 @@ +// +using System; +using BarDatabaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace BarDatabaseImplement.Migrations +{ + [DbContext(typeof(BarDatabase))] + [Migration("20240621140852_2")] + partial class _2 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("BarDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Cocktail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CocktailName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("Cocktails"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.CocktailComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CocktailId") + .HasColumnType("integer"); + + b.Property("ComponentId") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CocktailId"); + + b.HasIndex("ComponentId"); + + b.ToTable("CocktailComponents"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Cost") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.Property("Qualification") + .HasColumnType("integer"); + + b.Property("WorkExperience") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("CocktailId") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("DateCreate") + .HasColumnType("timestamp without time zone"); + + b.Property("DateImplement") + .HasColumnType("timestamp without time zone"); + + b.Property("ImplementerId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Sum") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.HasIndex("CocktailId"); + + b.HasIndex("ImplementerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.CocktailComponent", b => + { + b.HasOne("BarDatabaseImplement.Models.Cocktail", "Cocktail") + .WithMany("Components") + .HasForeignKey("CocktailId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BarDatabaseImplement.Models.Component", "Component") + .WithMany("CocktailComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Cocktail"); + + b.Navigation("Component"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Order", b => + { + b.HasOne("BarDatabaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BarDatabaseImplement.Models.Cocktail", "Cocktail") + .WithMany("Orders") + .HasForeignKey("CocktailId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BarDatabaseImplement.Models.Implementer", null) + .WithMany("Order") + .HasForeignKey("ImplementerId"); + + b.Navigation("Client"); + + b.Navigation("Cocktail"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Cocktail", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Component", b => + { + b.Navigation("CocktailComponents"); + }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Implementer", b => + { + b.Navigation("Order"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/20240621140852_2.cs b/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/20240621140852_2.cs new file mode 100644 index 0000000..1ac8bf8 --- /dev/null +++ b/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/20240621140852_2.cs @@ -0,0 +1,65 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace BarDatabaseImplement.Migrations +{ + public partial class _2 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ImplementerId", + table: "Orders", + type: "integer", + nullable: true); + + migrationBuilder.CreateTable( + name: "Implementers", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ImplementerFIO = table.Column(type: "text", nullable: false), + Password = table.Column(type: "text", nullable: false), + WorkExperience = table.Column(type: "integer", nullable: false), + Qualification = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Implementers", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Orders_ImplementerId", + table: "Orders", + column: "ImplementerId"); + + migrationBuilder.AddForeignKey( + name: "FK_Orders_Implementers_ImplementerId", + table: "Orders", + column: "ImplementerId", + principalTable: "Implementers", + principalColumn: "Id"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Orders_Implementers_ImplementerId", + table: "Orders"); + + migrationBuilder.DropTable( + name: "Implementers"); + + migrationBuilder.DropIndex( + name: "IX_Orders_ImplementerId", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "ImplementerId", + table: "Orders"); + } + } +} diff --git a/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/BarDatabaseModelSnapshot.cs b/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/BarDatabaseModelSnapshot.cs index 0904fb2..57d591c 100644 --- a/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/BarDatabaseModelSnapshot.cs +++ b/Bar/BarDatabaseImplement/BarDatabaseImplement/Migrations/BarDatabaseModelSnapshot.cs @@ -113,6 +113,33 @@ namespace BarDatabaseImplement.Migrations b.ToTable("Components"); }); + modelBuilder.Entity("BarDatabaseImplement.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.Property("Qualification") + .HasColumnType("integer"); + + b.Property("WorkExperience") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + modelBuilder.Entity("BarDatabaseImplement.Models.Order", b => { b.Property("Id") @@ -136,6 +163,9 @@ namespace BarDatabaseImplement.Migrations b.Property("DateImplement") .HasColumnType("timestamp without time zone"); + b.Property("ImplementerId") + .HasColumnType("integer"); + b.Property("Status") .HasColumnType("integer"); @@ -148,6 +178,8 @@ namespace BarDatabaseImplement.Migrations b.HasIndex("CocktailId"); + b.HasIndex("ImplementerId"); + b.ToTable("Orders"); }); @@ -184,6 +216,10 @@ namespace BarDatabaseImplement.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("BarDatabaseImplement.Models.Implementer", null) + .WithMany("Order") + .HasForeignKey("ImplementerId"); + b.Navigation("Client"); b.Navigation("Cocktail"); @@ -205,6 +241,11 @@ namespace BarDatabaseImplement.Migrations { b.Navigation("CocktailComponents"); }); + + modelBuilder.Entity("BarDatabaseImplement.Models.Implementer", b => + { + b.Navigation("Order"); + }); #pragma warning restore 612, 618 } } diff --git a/Bar/BarDatabaseImplement/BarDatabaseImplement/Models/Implementer.cs b/Bar/BarDatabaseImplement/BarDatabaseImplement/Models/Implementer.cs new file mode 100644 index 0000000..aeab1fc --- /dev/null +++ b/Bar/BarDatabaseImplement/BarDatabaseImplement/Models/Implementer.cs @@ -0,0 +1,64 @@ +using BarContracts.BindingModels; +using BarContracts.ViewModels; +using BarDataModels.Models; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace BarDatabaseImplement.Models +{ + public class Implementer : IImplementerModel + { + public int Id { get; set; } + + [Required] + public string ImplementerFIO { get; set; } = string.Empty; + + [Required] + public string Password { get; set; } = string.Empty; + + [Required] + public int WorkExperience { get; set; } + + [Required] + public int Qualification { get; set; } + + [ForeignKey("ImplementerId")] + public virtual List Order { get; set; } = new(); + + public static Implementer? Create(ImplementerBindingModel? Model) + { + if (Model == null) + return null; + + return new Implementer() + { + Id = Model.Id, + ImplementerFIO = Model.ImplementerFIO, + Password = Model.Password, + WorkExperience = Model.WorkExperience, + Qualification = Model.Qualification + }; + } + + public void Update(ImplementerBindingModel Model) + { + if (Model == null) + { + return; + } + ImplementerFIO = Model.ImplementerFIO; + Password = Model.Password; + WorkExperience = Model.WorkExperience; + Qualification = Model.Qualification; + } + + public ImplementerViewModel GetViewModel => new() + { + Id = Id, + ImplementerFIO = ImplementerFIO, + Password = Password, + WorkExperience = WorkExperience, + Qualification = Qualification + }; + } +} diff --git a/Bar/BarDatabaseImplement/BarDatabaseImplement/Models/Order.cs b/Bar/BarDatabaseImplement/BarDatabaseImplement/Models/Order.cs index 18d658a..21dc388 100644 --- a/Bar/BarDatabaseImplement/BarDatabaseImplement/Models/Order.cs +++ b/Bar/BarDatabaseImplement/BarDatabaseImplement/Models/Order.cs @@ -19,7 +19,10 @@ namespace BarDatabaseImplement.Models public int ClientId { get; private set; } public virtual Client Client { get; set; } - + public int? ImplementerId { get; private set; } + + public virtual Implementer? Implementer { get; set; } + [Required] public int Count { get; private set; } @@ -44,6 +47,7 @@ namespace BarDatabaseImplement.Models Id = Model.Id, CocktailId = Model.CocktailId, ClientId = Model.ClientId, + ImplementerId = Model.ImplementerId, Count = Model.Count, Sum = Model.Sum, Status = Model.Status, @@ -57,6 +61,7 @@ namespace BarDatabaseImplement.Models if (Model is null) return; + ImplementerId = Model.ImplementerId; Status = Model.Status; DateImplement = Model.DateImplement; } @@ -66,8 +71,10 @@ namespace BarDatabaseImplement.Models Id = Id, CocktailId = CocktailId, ClientId = ClientId, + ImplementerId = ImplementerId, CocktailName = Cocktail.CocktailName, ClientFIO = Client.ClientFIO, + ImplementerFIO = Implementer?.ImplementerFIO, Count = Count, Sum = Sum, Status = Status, diff --git a/Bar/BarRestApi/Controllers/ImplementerController.cs b/Bar/BarRestApi/Controllers/ImplementerController.cs new file mode 100644 index 0000000..e98f221 --- /dev/null +++ b/Bar/BarRestApi/Controllers/ImplementerController.cs @@ -0,0 +1,108 @@ +using BarContracts.BindingModels; +using BarContracts.BusinessLogicContracts; +using BarContracts.BusinessLogicsContracts; +using BarContracts.SearchModels; +using BarContracts.ViewModels; +using BarDataModels.Enums; +using Microsoft.AspNetCore.Mvc; + +namespace BarRestApi.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class ImplementerController : Controller + { + private readonly ILogger _logger; + + private readonly IOrderLogic _order; + + private readonly IImplementerLogic _logic; + + public ImplementerController(IOrderLogic Order, IImplementerLogic Logic, ILogger Logger) + { + _logger = Logger; + _order = Order; + _logic = Logic; + } + + [HttpGet] + public ImplementerViewModel? Login(string login, string password) + { + try + { + return _logic.ReadElement(new ImplementerSearchModel + { + ImplementerFIO = login, + Password = password + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка авторизации сотрудника"); + throw; + } + } + + [HttpGet] + public List? GetNewOrders() + { + try + { + return _order.ReadList(new OrderSearchModel + { + Status = OrderStatus.Accepted + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения новых заказов"); + throw; + } + } + + [HttpGet] + public OrderViewModel? GetImplementerOrder(int implementerId) + { + try + { + return _order.ReadElement(new OrderSearchModel + { + ImplementerId = implementerId + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения текущего заказа исполнителя"); + throw; + } + } + + [HttpPost] + public void TakeOrderInWork(OrderBindingModel Model) + { + try + { + _order.TakeOrderInWork(Model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка перевода заказа с №{Id} в работу", Model.Id); + throw; + } + } + + [HttpPost] + public void FinishOrder(OrderBindingModel Model) + { + try + { + _order.FinishOrder(Model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка отметки о готовности заказа с №{Id}", Model.Id); + throw; + } + } + } +}