diff --git a/FlowerShop/FlowerShop/FormImplementer.Designer.cs b/FlowerShop/FlowerShop/FormImplementer.Designer.cs new file mode 100644 index 0000000..b5e4521 --- /dev/null +++ b/FlowerShop/FlowerShop/FormImplementer.Designer.cs @@ -0,0 +1,172 @@ +namespace FlowerShopView +{ + 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/FlowerShop/FlowerShop/FormImplementer.cs b/FlowerShop/FlowerShop/FormImplementer.cs new file mode 100644 index 0000000..1376e46 --- /dev/null +++ b/FlowerShop/FlowerShop/FormImplementer.cs @@ -0,0 +1,105 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.SearchModels; +using Microsoft.Extensions.Logging; + +namespace FlowerShopView +{ + 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/FlowerShop/FlowerShop/FormImplementer.resx b/FlowerShop/FlowerShop/FormImplementer.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/FlowerShop/FlowerShop/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/FlowerShop/FlowerShop/FormImplementers.Designer.cs b/FlowerShop/FlowerShop/FormImplementers.Designer.cs new file mode 100644 index 0000000..d86d181 --- /dev/null +++ b/FlowerShop/FlowerShop/FormImplementers.Designer.cs @@ -0,0 +1,135 @@ +namespace FlowerShopView +{ + 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/FlowerShop/FlowerShop/FormImplementers.cs b/FlowerShop/FlowerShop/FormImplementers.cs new file mode 100644 index 0000000..4ebd464 --- /dev/null +++ b/FlowerShop/FlowerShop/FormImplementers.cs @@ -0,0 +1,111 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.BusinessLogicsContracts; +using Microsoft.Extensions.Logging; + +namespace FlowerShopView +{ + 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(FormImplementers)); + 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/FlowerShop/FlowerShop/FormImplementers.resx b/FlowerShop/FlowerShop/FormImplementers.resx new file mode 100644 index 0000000..a395bff --- /dev/null +++ b/FlowerShop/FlowerShop/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/FlowerShop/FlowerShop/FormMain.Designer.cs b/FlowerShop/FlowerShop/FormMain.Designer.cs index 02185c0..76e33b8 100644 --- a/FlowerShop/FlowerShop/FormMain.Designer.cs +++ b/FlowerShop/FlowerShop/FormMain.Designer.cs @@ -32,6 +32,8 @@ справочникиToolStripMenuItem = new ToolStripMenuItem(); ЦветыToolStripMenuItem = new ToolStripMenuItem(); КомпонентыToolStripMenuItem = new ToolStripMenuItem(); + клиентыToolStripMenuItem = new ToolStripMenuItem(); + исполнителиToolStripMenuItem = new ToolStripMenuItem(); отчётыToolStripMenuItem = new ToolStripMenuItem(); списокЦветковToolStripMenuItem = new ToolStripMenuItem(); компонентыПоЦветамToolStripMenuItem = new ToolStripMenuItem(); @@ -39,17 +41,15 @@ dataGridView = new DataGridView(); buttonCreateOrder = new Button(); buttonTakeOrderInWork = new Button(); - buttonOrderReady = new Button(); - buttonIssuedOrder = new Button(); buttonRef = new Button(); - клиентыToolStripMenuItem = new ToolStripMenuItem(); + запускToolStripMenuItem = new ToolStripMenuItem(); menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); SuspendLayout(); // // menuStrip1 // - menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчётыToolStripMenuItem }); + menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчётыToolStripMenuItem, запускToolStripMenuItem }); menuStrip1.Location = new Point(0, 0); menuStrip1.Name = "menuStrip1"; menuStrip1.Size = new Size(964, 24); @@ -58,7 +58,7 @@ // // справочникиToolStripMenuItem // - справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ЦветыToolStripMenuItem, КомпонентыToolStripMenuItem, клиентыToolStripMenuItem }); + справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ЦветыToolStripMenuItem, КомпонентыToolStripMenuItem, клиентыToolStripMenuItem, исполнителиToolStripMenuItem }); справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem"; справочникиToolStripMenuItem.Size = new Size(94, 20); справочникиToolStripMenuItem.Text = "Справочники"; @@ -77,6 +77,20 @@ КомпонентыToolStripMenuItem.Text = "Компоненты"; КомпонентыToolStripMenuItem.Click += КомпонентыToolStripMenuItem_Click; // + // клиентыToolStripMenuItem + // + клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem"; + клиентыToolStripMenuItem.Size = new Size(180, 22); + клиентыToolStripMenuItem.Text = "Клиенты"; + клиентыToolStripMenuItem.Click += клиентыToolStripMenuItem_Click; + // + // исполнителиToolStripMenuItem + // + исполнителиToolStripMenuItem.Name = "исполнителиToolStripMenuItem"; + исполнителиToolStripMenuItem.Size = new Size(180, 22); + исполнителиToolStripMenuItem.Text = "Исполнители"; + исполнителиToolStripMenuItem.Click += исполнителиToolStripMenuItem_Click; + // // отчётыToolStripMenuItem // отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { списокЦветковToolStripMenuItem, компонентыПоЦветамToolStripMenuItem, списокЗаказовToolStripMenuItem }); @@ -129,48 +143,28 @@ // buttonTakeOrderInWork.Location = new Point(775, 110); buttonTakeOrderInWork.Name = "buttonTakeOrderInWork"; - buttonTakeOrderInWork.Size = new Size(158, 34); + buttonTakeOrderInWork.Size = new Size(158, 32); buttonTakeOrderInWork.TabIndex = 3; buttonTakeOrderInWork.Text = "Отдать на выполнение"; buttonTakeOrderInWork.UseVisualStyleBackColor = true; buttonTakeOrderInWork.Click += ButtonTakeOrderInWork_Click; // - // buttonOrderReady - // - buttonOrderReady.Location = new Point(775, 168); - buttonOrderReady.Name = "buttonOrderReady"; - buttonOrderReady.Size = new Size(158, 34); - buttonOrderReady.TabIndex = 4; - buttonOrderReady.Text = "Заказ готов"; - buttonOrderReady.UseVisualStyleBackColor = true; - buttonOrderReady.Click += ButtonOrderReady_Click; - // - // buttonIssuedOrder - // - buttonIssuedOrder.Location = new Point(775, 230); - buttonIssuedOrder.Name = "buttonIssuedOrder"; - buttonIssuedOrder.Size = new Size(158, 34); - buttonIssuedOrder.TabIndex = 5; - buttonIssuedOrder.Text = "Заказ выдан"; - buttonIssuedOrder.UseVisualStyleBackColor = true; - buttonIssuedOrder.Click += ButtonIssuedOrder_Click; - // // buttonRef // - buttonRef.Location = new Point(775, 289); + buttonRef.Location = new Point(775, 165); buttonRef.Name = "buttonRef"; - buttonRef.Size = new Size(158, 34); + buttonRef.Size = new Size(158, 32); buttonRef.TabIndex = 6; buttonRef.Text = "Обновить список"; buttonRef.UseVisualStyleBackColor = true; buttonRef.Click += ButtonRef_Click; // - // клиентыToolStripMenuItem + // запускToolStripMenuItem // - клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem"; - клиентыToolStripMenuItem.Size = new Size(180, 22); - клиентыToolStripMenuItem.Text = "Клиенты"; - клиентыToolStripMenuItem.Click += клиентыToolStripMenuItem_Click; + запускToolStripMenuItem.Name = "запускToolStripMenuItem"; + запускToolStripMenuItem.Size = new Size(92, 20); + запускToolStripMenuItem.Text = "Запуск работ"; + запускToolStripMenuItem.Click += запускToolStripMenuItem_Click; // // FormMain // @@ -178,8 +172,6 @@ AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(964, 450); Controls.Add(buttonRef); - Controls.Add(buttonIssuedOrder); - Controls.Add(buttonOrderReady); Controls.Add(buttonTakeOrderInWork); Controls.Add(buttonCreateOrder); Controls.Add(dataGridView); @@ -204,13 +196,13 @@ private DataGridView dataGridView; private Button buttonCreateOrder; private Button buttonTakeOrderInWork; - private Button buttonOrderReady; - private Button buttonIssuedOrder; private Button buttonRef; private ToolStripMenuItem отчётыToolStripMenuItem; private ToolStripMenuItem списокЦветковToolStripMenuItem; private ToolStripMenuItem компонентыПоЦветамToolStripMenuItem; private ToolStripMenuItem списокЗаказовToolStripMenuItem; private ToolStripMenuItem клиентыToolStripMenuItem; + private ToolStripMenuItem исполнителиToolStripMenuItem; + private ToolStripMenuItem запускToolStripMenuItem; } } \ No newline at end of file diff --git a/FlowerShop/FlowerShop/FormMain.cs b/FlowerShop/FlowerShop/FormMain.cs index 417aec2..dd21605 100644 --- a/FlowerShop/FlowerShop/FormMain.cs +++ b/FlowerShop/FlowerShop/FormMain.cs @@ -10,12 +10,14 @@ namespace FlowerShopView 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) { @@ -32,8 +34,10 @@ namespace FlowerShopView dataGridView.DataSource = list; dataGridView.Columns["FlowerId"].Visible = false; dataGridView.Columns["ClientId"].Visible = false; + dataGridView.Columns["ImplementerId"].Visible = false; dataGridView.Columns["FlowerName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; } } catch (Exception ex) @@ -179,11 +183,26 @@ namespace FlowerShopView private void клиентыToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormClients)) ; + var service = Program.ServiceProvider?.GetService(typeof(FormClients)); if (service is FormClients form) { form.ShowDialog(); } } + + private void исполнителиToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormImplementers)); + if (service is FormImplementers form) + { + form.ShowDialog(); + } + } + + private void запускToolStripMenuItem_Click(object sender, EventArgs e) + { + _workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic); + MessageBox.Show("Процесс обработки запущен", "Сообщение",MessageBoxButtons.OK, MessageBoxIcon.Information); + } } } diff --git a/FlowerShop/FlowerShop/Program.cs b/FlowerShop/FlowerShop/Program.cs index 02d21f6..d334694 100644 --- a/FlowerShop/FlowerShop/Program.cs +++ b/FlowerShop/FlowerShop/Program.cs @@ -39,12 +39,15 @@ namespace FlowerShopView 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(); @@ -60,6 +63,8 @@ namespace FlowerShopView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file diff --git a/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/ImplementerLogic.cs b/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/ImplementerLogic.cs new file mode 100644 index 0000000..98a1cad --- /dev/null +++ b/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/ImplementerLogic.cs @@ -0,0 +1,128 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.StoragesContracts; +using FlowerShopContracts.ViewModels; +using Microsoft.Extensions.Logging; + +namespace FlowerShopBusinessLogic.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/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/OrderLogic.cs b/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/OrderLogic.cs index 12c6b6d..8b61226 100644 --- a/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/OrderLogic.cs @@ -1,4 +1,5 @@ -using FlowerShopContracts.BindingModels; +using DocumentFormat.OpenXml.EMMA; +using FlowerShopContracts.BindingModels; using FlowerShopContracts.BusinessLogicsContracts; using FlowerShopContracts.SearchModels; using FlowerShopContracts.StoragesContracts; @@ -12,6 +13,7 @@ namespace FlowerShopBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; + static readonly object _locker = new object(); public OrderLogic(ILogger logger, IOrderStorage orderStorage) { _logger = logger; @@ -29,7 +31,28 @@ namespace FlowerShopBusinessLogic.BusinessLogics _logger.LogInformation("ReadList. Count:{Count}", list.Count); return list; } - public bool CreateOrder(OrderBindingModel model) + public OrderViewModel? ReadElement(OrderSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + + _logger.LogInformation("ReadList. 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; + } + public bool CreateOrder(OrderBindingModel model) { CheckModel(model); if (model.Status != OrderStatus.Неизвестен) @@ -45,7 +68,10 @@ namespace FlowerShopBusinessLogic.BusinessLogics } public bool TakeOrderInWork(OrderBindingModel model) { - return ToNextStatus(model, OrderStatus.Выполняется); + lock (_locker) + { + return ToNextStatus(model, OrderStatus.Выполняется); + } } public bool FinishOrder(OrderBindingModel model) { @@ -71,7 +97,9 @@ namespace FlowerShopBusinessLogic.BusinessLogics model.FlowerId = element.FlowerId; model.DateCreate = element.DateCreate; model.DateImplement = element.DateImplement; - model.Status = element.Status; + model.ClientId = element.ClientId; + model.ImplementerId = element.ImplementerId; + model.Status = element.Status; model.Count = element.Count; model.Sum = element.Sum; diff --git a/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/WorkModeling.cs b/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/WorkModeling.cs new file mode 100644 index 0000000..f720fa1 --- /dev/null +++ b/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/WorkModeling.cs @@ -0,0 +1,120 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.ViewModels; +using FlowerShopDataModels.Enums; +using Microsoft.Extensions.Logging; + +namespace FlowerShopBusinessLogic.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.Принят + }); + if (orders == null || orders.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("DoWork. Worker {Id} try get order { Order}", implementer.Id, order.Id); + _orderLogic.TakeOrderInWork(new OrderBindingModel + { + Id = order.Id, + ImplementerId = implementer.Id + }); + Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count); + _logger.LogDebug("DoWork. 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.Выполняется + })); + if (runOrder == null) + { + return; + } + _logger.LogDebug("DoWork. Worker {Id} back to order {Order}", implementer.Id, runOrder.Id); + Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count); + _logger.LogDebug("DoWork. 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; + } + } + } +} \ No newline at end of file diff --git a/FlowerShop/FlowerShopContracts/BindingModels/OrderBindingModel.cs b/FlowerShop/FlowerShopContracts/BindingModels/OrderBindingModel.cs index 83ced06..0953b1b 100644 --- a/FlowerShop/FlowerShopContracts/BindingModels/OrderBindingModel.cs +++ b/FlowerShop/FlowerShopContracts/BindingModels/OrderBindingModel.cs @@ -8,7 +8,7 @@ namespace FlowerShopContracts.BindingModels public int Id { get; set; } public int FlowerId { get; set; } public int ClientId { get; set; } - public int ImplementerId { get; set; } = 0; + public int? ImplementerId { get; set; } public int Count { get; set; } public double Sum { get; set; } public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; diff --git a/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IOrderLogic.cs b/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IOrderLogic.cs index 0449bf8..b6898cf 100644 --- a/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IOrderLogic.cs +++ b/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IOrderLogic.cs @@ -7,6 +7,7 @@ namespace FlowerShopContracts.BusinessLogicsContracts public interface IOrderLogic { List? ReadList(OrderSearchModel? model); + OrderViewModel? ReadElement(OrderSearchModel? model); bool CreateOrder(OrderBindingModel model); bool TakeOrderInWork(OrderBindingModel model); bool FinishOrder(OrderBindingModel model); diff --git a/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IWorkProcess.cs b/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IWorkProcess.cs new file mode 100644 index 0000000..ac363fe --- /dev/null +++ b/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IWorkProcess.cs @@ -0,0 +1,8 @@ +namespace FlowerShopContracts.BusinessLogicsContracts +{ + public interface IWorkProcess + { + void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic); + } + +} diff --git a/FlowerShop/FlowerShopContracts/ViewModels/OrderViewModel.cs b/FlowerShop/FlowerShopContracts/ViewModels/OrderViewModel.cs index 9fd1640..96038ac 100644 --- a/FlowerShop/FlowerShopContracts/ViewModels/OrderViewModel.cs +++ b/FlowerShop/FlowerShopContracts/ViewModels/OrderViewModel.cs @@ -10,7 +10,7 @@ namespace FlowerShopContracts.ViewModels public int Id { get; set; } public int FlowerId { get; set; } public int ClientId { get; set; } - public int ImplementerId { get; set; } = 0; + public int? ImplementerId { get; set; } [DisplayName("Изделие")] public string FlowerName { get; set; } = string.Empty; [DisplayName("ФИО клиента")] diff --git a/FlowerShop/FlowerShopDataModels/Models/IOrderModel.cs b/FlowerShop/FlowerShopDataModels/Models/IOrderModel.cs index 35fc0f6..5ab5137 100644 --- a/FlowerShop/FlowerShopDataModels/Models/IOrderModel.cs +++ b/FlowerShop/FlowerShopDataModels/Models/IOrderModel.cs @@ -6,7 +6,7 @@ namespace FlowerShopDataModels.Models { int FlowerId { get; } int ClientId { get; } - int ImplementerId { get; } + int? ImplementerId { get; } int Count { get; } double Sum { get; } OrderStatus Status { get; } diff --git a/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj b/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj index 6a2cfd7..436990e 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj +++ b/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj @@ -21,8 +21,4 @@ - - - - diff --git a/FlowerShop/FlowerShopDatabaseImplement/Implements/OrderStorage.cs b/FlowerShop/FlowerShopDatabaseImplement/Implements/OrderStorage.cs index a07dde6..6e454c2 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Implements/OrderStorage.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Implements/OrderStorage.cs @@ -17,10 +17,6 @@ namespace FlowerShopDatabaseImplement.Implements } public List GetFilteredList(OrderSearchModel model) { - if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ClientId.HasValue) - { - return new(); - } using var context = new FlowerShopDatabase(); if (model.DateFrom.HasValue) return context.Orders diff --git a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240404125520_initcreate.Designer.cs b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240418172148_InitCreate.Designer.cs similarity index 81% rename from FlowerShop/FlowerShopDatabaseImplement/Migrations/20240404125520_initcreate.Designer.cs rename to FlowerShop/FlowerShopDatabaseImplement/Migrations/20240418172148_InitCreate.Designer.cs index 9138f8b..0384535 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240404125520_initcreate.Designer.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240418172148_InitCreate.Designer.cs @@ -12,8 +12,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace FlowerShopDatabaseImplement.Migrations { [DbContext(typeof(FlowerShopDatabase))] - [Migration("20240404125520_initcreate")] - partial class initcreate + [Migration("20240418172148_InitCreate")] + partial class InitCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) { @@ -115,6 +115,33 @@ namespace FlowerShopDatabaseImplement.Migrations b.ToTable("FlowerComponents"); }); + modelBuilder.Entity("FlowerShopDatabaseImplement.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("FlowerShopDatabaseImplement.Models.Order", b => { b.Property("Id") @@ -138,6 +165,9 @@ namespace FlowerShopDatabaseImplement.Migrations b.Property("FlowerId") .HasColumnType("integer"); + b.Property("ImplementerId") + .HasColumnType("integer"); + b.Property("Status") .HasColumnType("integer"); @@ -148,6 +178,8 @@ namespace FlowerShopDatabaseImplement.Migrations b.HasIndex("FlowerId"); + b.HasIndex("ImplementerId"); + b.ToTable("Orders"); }); @@ -177,6 +209,10 @@ namespace FlowerShopDatabaseImplement.Migrations .HasForeignKey("FlowerId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.HasOne("FlowerShopDatabaseImplement.Models.Implementer", null) + .WithMany("Order") + .HasForeignKey("ImplementerId"); }); modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => @@ -190,6 +226,11 @@ namespace FlowerShopDatabaseImplement.Migrations b.Navigation("Orders"); }); + + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Implementer", b => + { + b.Navigation("Order"); + }); #pragma warning restore 612, 618 } } diff --git a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240404125520_initcreate.cs b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240418172148_InitCreate.cs similarity index 80% rename from FlowerShop/FlowerShopDatabaseImplement/Migrations/20240404125520_initcreate.cs rename to FlowerShop/FlowerShopDatabaseImplement/Migrations/20240418172148_InitCreate.cs index 7a650bc..6bcd782 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240404125520_initcreate.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240418172148_InitCreate.cs @@ -6,7 +6,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace FlowerShopDatabaseImplement.Migrations { - public partial class initcreate : Migration + public partial class InitCreate : Migration { protected override void Up(MigrationBuilder migrationBuilder) { @@ -53,6 +53,22 @@ namespace FlowerShopDatabaseImplement.Migrations table.PrimaryKey("PK_Flowers", x => x.Id); }); + 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.CreateTable( name: "FlowerComponents", columns: table => new @@ -88,6 +104,7 @@ namespace FlowerShopDatabaseImplement.Migrations .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), FlowerId = table.Column(type: "integer", nullable: false), ClientId = table.Column(type: "integer", nullable: false), + ImplementerId = table.Column(type: "integer", nullable: true), Count = table.Column(type: "integer", nullable: false), Sum = table.Column(type: "double precision", nullable: false), Status = table.Column(type: "integer", nullable: false), @@ -103,6 +120,11 @@ namespace FlowerShopDatabaseImplement.Migrations principalTable: "Flowers", principalColumn: "Id", onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Orders_Implementers_ImplementerId", + column: x => x.ImplementerId, + principalTable: "Implementers", + principalColumn: "Id"); }); migrationBuilder.CreateIndex( @@ -119,6 +141,11 @@ namespace FlowerShopDatabaseImplement.Migrations name: "IX_Orders_FlowerId", table: "Orders", column: "FlowerId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_ImplementerId", + table: "Orders", + column: "ImplementerId"); } protected override void Down(MigrationBuilder migrationBuilder) @@ -137,6 +164,9 @@ namespace FlowerShopDatabaseImplement.Migrations migrationBuilder.DropTable( name: "Flowers"); + + migrationBuilder.DropTable( + name: "Implementers"); } } } diff --git a/FlowerShop/FlowerShopDatabaseImplement/Migrations/FlowerShopDatabaseModelSnapshot.cs b/FlowerShop/FlowerShopDatabaseImplement/Migrations/FlowerShopDatabaseModelSnapshot.cs index 0d55adb..0ccf3ca 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Migrations/FlowerShopDatabaseModelSnapshot.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Migrations/FlowerShopDatabaseModelSnapshot.cs @@ -113,6 +113,33 @@ namespace FlowerShopDatabaseImplement.Migrations b.ToTable("FlowerComponents"); }); + modelBuilder.Entity("FlowerShopDatabaseImplement.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("FlowerShopDatabaseImplement.Models.Order", b => { b.Property("Id") @@ -136,6 +163,9 @@ namespace FlowerShopDatabaseImplement.Migrations b.Property("FlowerId") .HasColumnType("integer"); + b.Property("ImplementerId") + .HasColumnType("integer"); + b.Property("Status") .HasColumnType("integer"); @@ -146,6 +176,8 @@ namespace FlowerShopDatabaseImplement.Migrations b.HasIndex("FlowerId"); + b.HasIndex("ImplementerId"); + b.ToTable("Orders"); }); @@ -175,6 +207,10 @@ namespace FlowerShopDatabaseImplement.Migrations .HasForeignKey("FlowerId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.HasOne("FlowerShopDatabaseImplement.Models.Implementer", null) + .WithMany("Order") + .HasForeignKey("ImplementerId"); }); modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => @@ -188,6 +224,11 @@ namespace FlowerShopDatabaseImplement.Migrations b.Navigation("Orders"); }); + + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Implementer", b => + { + b.Navigation("Order"); + }); #pragma warning restore 612, 618 } } diff --git a/FlowerShop/FlowerShopDatabaseImplement/Models/Order.cs b/FlowerShop/FlowerShopDatabaseImplement/Models/Order.cs index f2bdb9b..87ff7a2 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Models/Order.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Models/Order.cs @@ -11,7 +11,7 @@ namespace FlowerShopDatabaseImplement.Models public int Id { get; private set; } public int FlowerId { get; private set; } public int ClientId { get; private set; } - public int ImplementerId { get; private set; } + public int? ImplementerId { get; private set; } [Required] public int Count { get; set; } [Required] @@ -32,6 +32,7 @@ namespace FlowerShopDatabaseImplement.Models Id = model.Id, FlowerId = model.FlowerId, ClientId = model.ClientId, + ImplementerId = model.ImplementerId, Count = model.Count, Sum = model.Sum, Status = model.Status, @@ -45,6 +46,7 @@ namespace FlowerShopDatabaseImplement.Models { return; } + ImplementerId = model.ImplementerId; Status = model.Status; DateImplement = model.DateImplement; } @@ -53,6 +55,7 @@ namespace FlowerShopDatabaseImplement.Models Id = Id, FlowerId = FlowerId, ClientId = ClientId, + ImplementerId = ImplementerId, Count = Count, Sum = Sum, Status = Status, diff --git a/FlowerShop/FlowerShopFileImplement/DataFileSingleton.cs b/FlowerShop/FlowerShopFileImplement/DataFileSingleton.cs index af08faf..b3c3b6f 100644 --- a/FlowerShop/FlowerShopFileImplement/DataFileSingleton.cs +++ b/FlowerShop/FlowerShopFileImplement/DataFileSingleton.cs @@ -10,7 +10,7 @@ namespace FlowerShopFileImplement private readonly string OrderFileName = "Order.xml"; private readonly string FlowerFileName = "Flower.xml"; private readonly string ClientFileName = "Client.xml"; - private readonly string ImplementerFileName = "Implementer.xml" + private readonly string ImplementerFileName = "Implementer.xml"; public List Components { get; private set; } public List Orders { get; private set; } public List Flowers { get; private set; } @@ -35,7 +35,7 @@ namespace FlowerShopFileImplement Flowers = LoadData(FlowerFileName, "Flower", x => Flower.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!; - Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!); + Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!; } private static List? LoadData(string filename, string xmlNodeName, Func selectFunction) { diff --git a/FlowerShop/FlowerShopFileImplement/Models/Order.cs b/FlowerShop/FlowerShopFileImplement/Models/Order.cs index 9812a33..594dec8 100644 --- a/FlowerShop/FlowerShopFileImplement/Models/Order.cs +++ b/FlowerShop/FlowerShopFileImplement/Models/Order.cs @@ -11,7 +11,7 @@ namespace FlowerShopFileImplement.Models public int Id { get; private set; } public int FlowerId { get; private set; } public int ClientId { get; private set; } - public int ImplementerId { get; private set; } + public int? ImplementerId { get; private set; } public int Count { get; private set; } public double Sum { get; set; } public OrderStatus Status { get; set; } diff --git a/FlowerShop/FlowerShopListImplement/Models/Order.cs b/FlowerShop/FlowerShopListImplement/Models/Order.cs index 9c26708..d36c7d6 100644 --- a/FlowerShop/FlowerShopListImplement/Models/Order.cs +++ b/FlowerShop/FlowerShopListImplement/Models/Order.cs @@ -10,7 +10,7 @@ namespace FlowerShopListImplement.Models public int Id { get; private set; } public int FlowerId { get; private set; } public int ClientId { get; private set; } - public int ImplementerId { get; private set; } + public int? ImplementerId { get; private set; } public int Count { get; set; } public double Sum { get; private set; } public OrderStatus Status { get; set; } diff --git a/FlowerShop/FlowerShopRestApi/Controllers/ImplementerController.cs b/FlowerShop/FlowerShopRestApi/Controllers/ImplementerController.cs new file mode 100644 index 0000000..a2fd78d --- /dev/null +++ b/FlowerShop/FlowerShopRestApi/Controllers/ImplementerController.cs @@ -0,0 +1,100 @@ +using DocumentFormat.OpenXml.Office2010.Excel; +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.ViewModels; +using FlowerShopDataModels.Enums; +using Microsoft.AspNetCore.Mvc; + +namespace FlowerShopRestApi.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.Принят + }); + } + 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; + } + } + } +} \ No newline at end of file