diff --git a/GarmentFactory/FormAddTextile.Designer.cs b/GarmentFactory/FormAddTextile.Designer.cs new file mode 100644 index 0000000..11c88bb --- /dev/null +++ b/GarmentFactory/FormAddTextile.Designer.cs @@ -0,0 +1,144 @@ +namespace GarmentFactoryView +{ + partial class FormAddTextile + { + /// + /// 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() + { + labelShop = new Label(); + labelCount = new Label(); + labelTextile = new Label(); + comboBoxShop = new ComboBox(); + textBoxCount = new TextBox(); + comboBoxTextile = new ComboBox(); + buttonCancel = new Button(); + buttonSave = new Button(); + SuspendLayout(); + // + // labelShop + // + labelShop.AutoSize = true; + labelShop.Location = new Point(38, 37); + labelShop.Name = "labelShop"; + labelShop.Size = new Size(72, 20); + labelShop.TabIndex = 0; + labelShop.Text = "Магазин:"; + // + // labelCount + // + labelCount.AutoSize = true; + labelCount.Location = new Point(29, 123); + labelCount.Name = "labelCount"; + labelCount.Size = new Size(93, 20); + labelCount.TabIndex = 3; + labelCount.Text = "Количество:"; + // + // labelTextile + // + labelTextile.AutoSize = true; + labelTextile.Location = new Point(38, 79); + labelTextile.Name = "labelTextile"; + labelTextile.Size = new Size(71, 20); + labelTextile.TabIndex = 2; + labelTextile.Text = "Изделие:"; + // + // comboBoxShop + // + comboBoxShop.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxShop.FormattingEnabled = true; + comboBoxShop.Location = new Point(140, 37); + comboBoxShop.Name = "comboBoxShop"; + comboBoxShop.Size = new Size(262, 28); + comboBoxShop.TabIndex = 11; + // + // textBoxCount + // + textBoxCount.Location = new Point(140, 123); + textBoxCount.Name = "textBoxCount"; + textBoxCount.Size = new Size(262, 27); + textBoxCount.TabIndex = 10; + // + // comboBoxTextile + // + comboBoxTextile.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxTextile.FormattingEnabled = true; + comboBoxTextile.Location = new Point(140, 79); + comboBoxTextile.Name = "comboBoxTextile"; + comboBoxTextile.Size = new Size(262, 28); + comboBoxTextile.TabIndex = 9; + // + // buttonCancel + // + buttonCancel.Location = new Point(342, 181); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(94, 29); + buttonCancel.TabIndex = 13; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += ButtonCancel_Click; + // + // buttonSave + // + buttonSave.Location = new Point(242, 181); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(94, 29); + buttonSave.TabIndex = 12; + buttonSave.Text = "Сохранить"; + buttonSave.UseVisualStyleBackColor = true; + buttonSave.Click += ButtonSave_Click; + // + // FormAddTextile + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(455, 222); + Controls.Add(buttonCancel); + Controls.Add(buttonSave); + Controls.Add(comboBoxShop); + Controls.Add(textBoxCount); + Controls.Add(comboBoxTextile); + Controls.Add(labelCount); + Controls.Add(labelTextile); + Controls.Add(labelShop); + Name = "FormAddTextile"; + Text = "Пополнение магазина"; + Load += FormAddTextile_Load; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label labelShop; + private Label labelCount; + private Label labelTextile; + private ComboBox comboBoxShop; + private TextBox textBoxCount; + private ComboBox comboBoxTextile; + private Button buttonCancel; + private Button buttonSave; + } +} \ No newline at end of file diff --git a/GarmentFactory/FormAddTextile.cs b/GarmentFactory/FormAddTextile.cs new file mode 100644 index 0000000..0b26d2b --- /dev/null +++ b/GarmentFactory/FormAddTextile.cs @@ -0,0 +1,109 @@ +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.BusinessLogicsContracts; +using GarmentFactoryContracts.SearchModels; +using GarmentFactoryContracts.ViewModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace GarmentFactoryView +{ + public partial class FormAddTextile : Form + { + private readonly ILogger _logger; + private readonly ITextileLogic _logicT; + private readonly IShopLogic _logicS; + //Списки для ComboBox + private List _shopList = new List(); + private List _textileList = new List(); + public FormAddTextile(ILogger logger, ITextileLogic logicT, IShopLogic logicS) + { + InitializeComponent(); + _logger = logger; + _logicT = logicT; + _logicS = logicS; + } + + private void FormAddTextile_Load(object sender, EventArgs e) + { + _shopList = _logicS.ReadList(null); + _textileList = _logicT.ReadList(null); + + _logger.LogInformation("Загрузка списка магазинов при пополнении"); + if (_shopList != null) + { + comboBoxShop.DisplayMember = "ShopName"; + comboBoxShop.ValueMember = "Id"; + comboBoxShop.DataSource = _shopList; + comboBoxShop.SelectedItem = null; + } + + _logger.LogInformation("Загрузка списка товаров при пополнении"); + if (_textileList != null) + { + comboBoxTextile.DisplayMember = "TextileName"; + comboBoxTextile.ValueMember = "Id"; + comboBoxTextile.DataSource = _textileList; + comboBoxTextile.SelectedItem = null; + } + } + + private void ButtonSave_Click(object sender, EventArgs e) + { + if (comboBoxShop.SelectedValue == null) + { + MessageBox.Show("Выберите магазин", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (comboBoxTextile.SelectedValue == null) + { + MessageBox.Show("Выберите изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (string.IsNullOrEmpty(textBoxCount.Text)) + { + MessageBox.Show("Заполните поле \"Количество\"", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + _logger.LogInformation("Пополнение магазина"); + try + { + var operationResult = _logicS.MakeSupply(new SupplyBindingModel + { + ShopId = Convert.ToInt32(comboBoxShop.SelectedValue), + TextileId = Convert.ToInt32(comboBoxTextile.SelectedValue), + Count = Convert.ToInt32(textBoxCount.Text) + }); + + 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 ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/GarmentFactory/FormAddTextile.resx b/GarmentFactory/FormAddTextile.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/GarmentFactory/FormAddTextile.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/GarmentFactory/FormMain.Designer.cs b/GarmentFactory/FormMain.Designer.cs index e53341c..b97857c 100644 --- a/GarmentFactory/FormMain.Designer.cs +++ b/GarmentFactory/FormMain.Designer.cs @@ -1,26 +1,26 @@ namespace GarmentFactoryView { - partial class FormMain - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; + partial class FormMain + { + /// + /// 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); - } + /// + /// 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 + #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify @@ -38,6 +38,10 @@ справочникиToolStripMenuItem = new ToolStripMenuItem(); компонентыToolStripMenuItem = new ToolStripMenuItem(); текстилиToolStripMenuItem = new ToolStripMenuItem(); + магазиныToolStripMenuItem = new ToolStripMenuItem(); + операцииToolStripMenuItem = new ToolStripMenuItem(); + пополнениеМагазинаToolStripMenuItem1 = new ToolStripMenuItem(); + продажаТовараToolStripMenuItem = new ToolStripMenuItem(); отчётыToolStripMenuItem = new ToolStripMenuItem(); textilesToolStripMenuItem = new ToolStripMenuItem(); textileComponentsToolStripMenuItem = new ToolStripMenuItem(); @@ -148,6 +152,34 @@ текстилиToolStripMenuItem.Text = "Текстили"; текстилиToolStripMenuItem.Click += текстилиToolStripMenuItem_Click; // + // магазиныToolStripMenuItem + // + магазиныToolStripMenuItem.Name = "магазиныToolStripMenuItem"; + магазиныToolStripMenuItem.Size = new Size(182, 26); + магазиныToolStripMenuItem.Text = "Магазины"; + магазиныToolStripMenuItem.Click += магазиныToolStripMenuItem_Click; + // + // операцииToolStripMenuItem + // + операцииToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { пополнениеМагазинаToolStripMenuItem1, продажаТовараToolStripMenuItem }); + операцииToolStripMenuItem.Name = "операцииToolStripMenuItem"; + операцииToolStripMenuItem.Size = new Size(95, 24); + операцииToolStripMenuItem.Text = "Операции"; + // + // пополнениеМагазинаToolStripMenuItem1 + // + пополнениеМагазинаToolStripMenuItem1.Name = "пополнениеМагазинаToolStripMenuItem1"; + пополнениеМагазинаToolStripMenuItem1.Size = new Size(251, 26); + пополнениеМагазинаToolStripMenuItem1.Text = "Пополнение магазина"; + пополнениеМагазинаToolStripMenuItem1.Click += пополнениеМагазинаToolStripMenuItem1_Click; + // + // продажаТовараToolStripMenuItem + // + продажаТовараToolStripMenuItem.Name = "продажаТовараToolStripMenuItem"; + продажаТовараToolStripMenuItem.Size = new Size(251, 26); + продажаТовараToolStripMenuItem.Text = "Продажа товара"; + продажаТовараToolStripMenuItem.Click += продажаТовараToolStripMenuItem_Click; + // // отчётыToolStripMenuItem // отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { textilesToolStripMenuItem, textileComponentsToolStripMenuItem, ordersToolStripMenuItem }); @@ -199,7 +231,7 @@ PerformLayout(); } - #endregion + #endregion private DataGridView dataGridView; private Button buttonCreateOrder; @@ -211,6 +243,10 @@ private ToolStripMenuItem справочникиToolStripMenuItem; private ToolStripMenuItem компонентыToolStripMenuItem; private ToolStripMenuItem текстилиToolStripMenuItem; + private ToolStripMenuItem магазиныToolStripMenuItem; + private ToolStripMenuItem операцииToolStripMenuItem; + private ToolStripMenuItem пополнениеМагазинаToolStripMenuItem1; + private ToolStripMenuItem продажаТовараToolStripMenuItem; private ToolStripMenuItem отчётыToolStripMenuItem; private ToolStripMenuItem textilesToolStripMenuItem; private ToolStripMenuItem textileComponentsToolStripMenuItem; diff --git a/GarmentFactory/FormMain.cs b/GarmentFactory/FormMain.cs index d1969ba..4790f9d 100644 --- a/GarmentFactory/FormMain.cs +++ b/GarmentFactory/FormMain.cs @@ -20,7 +20,7 @@ namespace GarmentFactoryView private readonly ILogger _logger; private readonly IOrderLogic _orderLogic; private readonly IReportLogic _reportLogic; - public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic) + public FormMain(ILogger logger, IOrderLogic orderLogic) { InitializeComponent(); _logger = logger; @@ -52,15 +52,15 @@ namespace GarmentFactoryView LoadData(); } - private void компонентыToolStripMenuItem_Click(object sender, EventArgs e) - { - var service = Program.ServiceProvider?.GetService(typeof(FormComponents)); - if (service is FormComponents form) - { - form.ShowDialog(); - } + private void компонентыToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormComponents)); + if (service is FormComponents form) + { + form.ShowDialog(); + } - } + } private void текстилиToolStripMenuItem_Click(object sender, EventArgs e) { @@ -101,85 +101,115 @@ namespace GarmentFactoryView } - private void ButtonCreateOrder_Click(object sender, EventArgs e) - { - var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); - if (service is FormCreateOrder form) - { - form.ShowDialog(); - LoadData(); - } - } - private void ButtonTakeOrderInWork_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id); - try - { - var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { Id = id }); - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка передачи заказа в работу"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } - private void ButtonOrderReady_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id); - try - { - var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id }); - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка отметки о готовности заказа"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } - private void ButtonCompletedOrder_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id); - try - { - var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id }); - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - _logger.LogInformation("Заказ №{id} выдан", id); - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка отметки о выдачи заказа"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } - private void ButtonRefresh_Click(object sender, EventArgs e) - { - LoadData(); - } - } + + private void магазиныToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormShops)); + + if (service is FormShops form) + { + form.ShowDialog(); + } + } + + private void ButtonCreateOrder_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); + if (service is FormCreateOrder form) + { + form.ShowDialog(); + LoadData(); + } + } + private void ButtonTakeOrderInWork_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id); + try + { + var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { Id = id }); + if (!operationResult) + { + throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка передачи заказа в работу"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + private void ButtonOrderReady_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id); + try + { + var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id }); + if (!operationResult) + { + throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка отметки о готовности заказа"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + private void ButtonCompletedOrder_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id); + try + { + var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id }); + if (!operationResult) + { + throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); + } + _logger.LogInformation("Заказ №{id} выдан", id); + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка отметки о выдачи заказа"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + private void ButtonRefresh_Click(object sender, EventArgs e) + { + LoadData(); + } + + private void пополнениеМагазинаToolStripMenuItem1_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormAddTextile)); + + if (service is FormAddTextile form) + { + form.ShowDialog(); + } + } + + private void продажаТовараToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormSellTextile)); + if (service is FormSellTextile form) + { + form.ShowDialog(); + } + } + } } diff --git a/GarmentFactory/FormSellTextile.Designer.cs b/GarmentFactory/FormSellTextile.Designer.cs new file mode 100644 index 0000000..c21f0f5 --- /dev/null +++ b/GarmentFactory/FormSellTextile.Designer.cs @@ -0,0 +1,119 @@ +namespace GarmentFactoryView +{ + partial class FormSellTextile + { + /// + /// 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() + { + labelTextile = new Label(); + comboBoxTextile = new ComboBox(); + labelCount = new Label(); + textBoxCount = new TextBox(); + buttonSell = new Button(); + buttonCancel = new Button(); + SuspendLayout(); + // + // labelTextile + // + labelTextile.AutoSize = true; + labelTextile.Location = new Point(12, 14); + labelTextile.Name = "labelTextile"; + labelTextile.Size = new Size(77, 20); + labelTextile.TabIndex = 0; + labelTextile.Text = "Текстиль: "; + // + // comboBoxTextile + // + comboBoxTextile.FormattingEnabled = true; + comboBoxTextile.Location = new Point(115, 11); + comboBoxTextile.Name = "comboBoxTextile"; + comboBoxTextile.Size = new Size(239, 28); + comboBoxTextile.TabIndex = 1; + // + // labelCount + // + labelCount.AutoSize = true; + labelCount.Location = new Point(12, 55); + labelCount.Name = "labelCount"; + labelCount.Size = new Size(97, 20); + labelCount.TabIndex = 2; + labelCount.Text = "Количество: "; + // + // textBoxCount + // + textBoxCount.Location = new Point(115, 52); + textBoxCount.Name = "textBoxCount"; + textBoxCount.Size = new Size(239, 27); + textBoxCount.TabIndex = 3; + // + // buttonSell + // + buttonSell.Location = new Point(128, 99); + buttonSell.Name = "buttonSell"; + buttonSell.Size = new Size(94, 29); + buttonSell.TabIndex = 4; + buttonSell.Text = "Продать"; + buttonSell.UseVisualStyleBackColor = true; + buttonSell.Click += ButtonSell_Click; + // + // buttonCancel + // + buttonCancel.Location = new Point(242, 99); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(94, 29); + buttonCancel.TabIndex = 5; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += ButtonCancel_Click; + // + // FormSellTextile + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(366, 140); + Controls.Add(buttonCancel); + Controls.Add(buttonSell); + Controls.Add(textBoxCount); + Controls.Add(labelCount); + Controls.Add(comboBoxTextile); + Controls.Add(labelTextile); + Name = "FormSellTextile"; + Text = "Продажа текстиля"; + Load += FormSellingTextile_Load; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label labelTextile; + private ComboBox comboBoxTextile; + private Label labelCount; + private TextBox textBoxCount; + private Button buttonSell; + private Button buttonCancel; + } +} \ No newline at end of file diff --git a/GarmentFactory/FormSellTextile.cs b/GarmentFactory/FormSellTextile.cs new file mode 100644 index 0000000..b2a8705 --- /dev/null +++ b/GarmentFactory/FormSellTextile.cs @@ -0,0 +1,87 @@ +using GarmentFactoryContracts.BusinessLogicsContracts; +using GarmentFactoryContracts.SearchModels; +using GarmentFactoryContracts.ViewModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace GarmentFactoryView +{ + public partial class FormSellTextile : Form + { + private readonly ILogger _logger; + private readonly ITextileLogic _logicT; + private readonly IShopLogic _logicS; + private List _TextileList = new List(); + + public FormSellTextile(ILogger logger, ITextileLogic logicT, IShopLogic logicS) + { + InitializeComponent(); + _logger = logger; + _logicT = logicT; + _logicS = logicS; + } + + private void FormSellingTextile_Load(object sender, EventArgs e) + { + _TextileList = _logicT.ReadList(null); + if (_TextileList != null) + { + comboBoxTextile.DisplayMember = "TextileName"; + comboBoxTextile.ValueMember = "Id"; + comboBoxTextile.DataSource = _TextileList; + comboBoxTextile.SelectedItem = null; + _logger.LogInformation("Загрузка пиццы для продажи"); + } + } + + private void ButtonSell_Click(object sender, EventArgs e) + { + if (comboBoxTextile.SelectedValue == null) + { + MessageBox.Show("Выберите пиццу", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("Создание покупки"); + try + { + bool resout = _logicS.Sell(new SupplySearchModel + { + TextileId = Convert.ToInt32(comboBoxTextile.SelectedValue), + Count = Convert.ToInt32(textBoxCount.Text) + }); + if (resout) + { + _logger.LogInformation("Проверка была выполнена"); + MessageBox.Show("Продажа выполнена", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information); + DialogResult = DialogResult.OK; + Close(); + } + else + { + _logger.LogInformation("Проверка не пройдена"); + MessageBox.Show("Продажа не может быть выполнена.", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка создания покупки"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + private void ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/GarmentFactory/FormSellTextile.resx b/GarmentFactory/FormSellTextile.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/GarmentFactory/FormSellTextile.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/GarmentFactory/FormShop.Designer.cs b/GarmentFactory/FormShop.Designer.cs new file mode 100644 index 0000000..3e1c300 --- /dev/null +++ b/GarmentFactory/FormShop.Designer.cs @@ -0,0 +1,230 @@ +namespace GarmentFactoryView +{ + partial class FormShop + { + /// + /// 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() + { + labelName = new Label(); + labelAddress = new Label(); + labelDateOpen = new Label(); + textBoxName = new TextBox(); + textBoxAddress = new TextBox(); + dateTimePicker = new DateTimePicker(); + groupBoxTextiles = new GroupBox(); + dataGridView = new DataGridView(); + ID = new DataGridViewTextBoxColumn(); + ColumnTextileName = new DataGridViewTextBoxColumn(); + ColumnCount = new DataGridViewTextBoxColumn(); + buttonCancel = new Button(); + buttonSave = new Button(); + numericUpTextileMaxCount = new NumericUpDown(); + label2 = new Label(); + groupBoxTextiles.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); + ((System.ComponentModel.ISupportInitialize)numericUpTextileMaxCount).BeginInit(); + SuspendLayout(); + // + // labelName + // + labelName.AutoSize = true; + labelName.Location = new Point(30, 21); + labelName.Name = "labelName"; + labelName.Size = new Size(84, 20); + labelName.TabIndex = 0; + labelName.Text = "Название: "; + // + // labelAddress + // + labelAddress.AutoSize = true; + labelAddress.Location = new Point(40, 71); + labelAddress.Name = "labelAddress"; + labelAddress.Size = new Size(58, 20); + labelAddress.TabIndex = 1; + labelAddress.Text = "Адрес: "; + // + // labelDateOpen + // + labelDateOpen.AutoSize = true; + labelDateOpen.Location = new Point(12, 118); + labelDateOpen.Name = "labelDateOpen"; + labelDateOpen.Size = new Size(117, 20); + labelDateOpen.TabIndex = 2; + labelDateOpen.Text = "Дата открытия: "; + // + // textBoxName + // + textBoxName.Location = new Point(135, 21); + textBoxName.Name = "textBoxName"; + textBoxName.Size = new Size(243, 27); + textBoxName.TabIndex = 3; + // + // textBoxAddress + // + textBoxAddress.Location = new Point(135, 68); + textBoxAddress.Name = "textBoxAddress"; + textBoxAddress.Size = new Size(243, 27); + textBoxAddress.TabIndex = 4; + // + // dateTimePicker + // + dateTimePicker.Location = new Point(135, 113); + dateTimePicker.Name = "dateTimePicker"; + dateTimePicker.Size = new Size(243, 27); + dateTimePicker.TabIndex = 5; + // + // groupBoxTextiles + // + groupBoxTextiles.Controls.Add(dataGridView); + groupBoxTextiles.Location = new Point(12, 209); + groupBoxTextiles.Name = "groupBoxTextiles"; + groupBoxTextiles.Size = new Size(651, 306); + groupBoxTextiles.TabIndex = 6; + groupBoxTextiles.TabStop = false; + groupBoxTextiles.Text = "Изделия"; + // + // dataGridView + // + dataGridView.AllowUserToAddRows = false; + dataGridView.AllowUserToDeleteRows = false; + dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dataGridView.Columns.AddRange(new DataGridViewColumn[] { ID, ColumnTextileName, ColumnCount }); + dataGridView.Location = new Point(6, 26); + dataGridView.Name = "dataGridView"; + dataGridView.ReadOnly = true; + dataGridView.RowHeadersWidth = 51; + dataGridView.RowTemplate.Height = 29; + dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; + dataGridView.Size = new Size(633, 274); + dataGridView.TabIndex = 0; + // + // ID + // + ID.HeaderText = "ID"; + ID.MinimumWidth = 6; + ID.Name = "ID"; + ID.ReadOnly = true; + ID.Visible = false; + // + // ColumnTextileName + // + ColumnTextileName.HeaderText = "Изделие"; + ColumnTextileName.MinimumWidth = 6; + ColumnTextileName.Name = "ColumnTextileName"; + ColumnTextileName.ReadOnly = true; + // + // ColumnCount + // + ColumnCount.HeaderText = "Количество"; + ColumnCount.MinimumWidth = 6; + ColumnCount.Name = "ColumnCount"; + ColumnCount.ReadOnly = true; + // + // buttonCancel + // + buttonCancel.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point); + buttonCancel.Location = new Point(550, 532); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(103, 40); + buttonCancel.TabIndex = 9; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += ButtonCancel_Click; + // + // buttonSave + // + buttonSave.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point); + buttonSave.Location = new Point(432, 532); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(103, 40); + buttonSave.TabIndex = 8; + buttonSave.Text = "Сохранить"; + buttonSave.UseVisualStyleBackColor = true; + buttonSave.Click += ButtonSave_Click; + // + // numericUpTextileMaxCount + // + numericUpTextileMaxCount.Location = new Point(135, 163); + numericUpTextileMaxCount.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); + numericUpTextileMaxCount.Name = "numericUpTextileMaxCount"; + numericUpTextileMaxCount.Size = new Size(243, 27); + numericUpTextileMaxCount.TabIndex = 13; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new Point(19, 165); + label2.Name = "label2"; + label2.Size = new Size(103, 20); + label2.TabIndex = 12; + label2.Text = "Вместимость:"; + // + // FormShop + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(682, 584); + Controls.Add(numericUpTextileMaxCount); + Controls.Add(label2); + Controls.Add(buttonCancel); + Controls.Add(buttonSave); + Controls.Add(groupBoxTextiles); + Controls.Add(dateTimePicker); + Controls.Add(textBoxAddress); + Controls.Add(textBoxName); + Controls.Add(labelDateOpen); + Controls.Add(labelAddress); + Controls.Add(labelName); + Name = "FormShop"; + Text = "Магазин"; + Load += FormShop_Load; + groupBoxTextiles.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); + ((System.ComponentModel.ISupportInitialize)numericUpTextileMaxCount).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label labelName; + private Label labelAddress; + private Label labelDateOpen; + private TextBox textBoxName; + private TextBox textBoxAddress; + private DateTimePicker dateTimePicker; + private GroupBox groupBoxTextiles; + private DataGridView dataGridView; + private DataGridViewTextBoxColumn ID; + private DataGridViewTextBoxColumn ColumnTextileName; + private DataGridViewTextBoxColumn ColumnCount; + private Button buttonCancel; + private Button buttonSave; + private NumericUpDown numericUpTextileMaxCount; + private Label label2; + } +} \ No newline at end of file diff --git a/GarmentFactory/FormShop.cs b/GarmentFactory/FormShop.cs new file mode 100644 index 0000000..62a748c --- /dev/null +++ b/GarmentFactory/FormShop.cs @@ -0,0 +1,135 @@ +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.BusinessLogicsContracts; +using GarmentFactoryContracts.SearchModels; +using GarmentFactoryDataModels.Models; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace GarmentFactoryView +{ + public partial class FormShop : Form + { + private readonly ILogger _logger; + + private readonly IShopLogic _logic; + + private int? _id; + + public int Id { set { _id = value; } } + + private Dictionary _shopTextiles; + + + public FormShop(ILogger logger, IShopLogic logic) + { + InitializeComponent(); + _logger = logger; + _logic = logic; + _shopTextiles = new Dictionary(); + } + + private void FormShop_Load(object sender, EventArgs e) + { + if (_id.HasValue) + { + _logger.LogInformation("Загрузка магазина"); + try + { + var view = _logic.ReadElement(new ShopSearchModel + { + Id = _id.Value + }); + if (view != null) + { + textBoxName.Text = view.ShopName; + textBoxAddress.Text = view.Address.ToString(); + dateTimePicker.Value = view.DateOpen; + numericUpTextileMaxCount.Value = view.TextileMaxCount; + _shopTextiles = view.ShopTextiles ?? new Dictionary(); + LoadData(); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки магазина"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void LoadData() + { + _logger.LogInformation("Загрузка изделий в магазине"); + try + { + if (_shopTextiles != null) + { + dataGridView.Rows.Clear(); + foreach (var element in _shopTextiles) + { + dataGridView.Rows.Add(new object[] { element.Key, element.Value.Item1.TextileName, element.Value.Item2 }); + } + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки изделий в магазине"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonSave_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(textBoxName.Text)) + { + MessageBox.Show("Заполните название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (string.IsNullOrEmpty(textBoxAddress.Text)) + { + MessageBox.Show("Заполните адрес", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("Сохранение магазина"); + try + { + var model = new ShopBindingModel + { + Id = _id ?? 0, + ShopName = textBoxName.Text, + Address = textBoxAddress.Text, + DateOpen = dateTimePicker.Value.Date, + ShopTextiles = _shopTextiles, + TextileMaxCount = (int)numericUpTextileMaxCount.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 ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/GarmentFactory/FormShop.resx b/GarmentFactory/FormShop.resx new file mode 100644 index 0000000..bc99676 --- /dev/null +++ b/GarmentFactory/FormShop.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + True + + + True + + + True + + \ No newline at end of file diff --git a/GarmentFactory/FormShops.Designer.cs b/GarmentFactory/FormShops.Designer.cs new file mode 100644 index 0000000..1b50209 --- /dev/null +++ b/GarmentFactory/FormShops.Designer.cs @@ -0,0 +1,116 @@ +namespace GarmentFactoryView +{ + partial class FormShops + { + /// + /// 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() + { + dataGridView = new DataGridView(); + buttonRefresh = new Button(); + buttonDelete = new Button(); + buttonUpdate = new Button(); + buttonAdd = new Button(); + ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); + SuspendLayout(); + // + // dataGridView + // + dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dataGridView.Location = new Point(-3, -4); + dataGridView.Name = "dataGridView"; + dataGridView.ReadOnly = true; + dataGridView.RowHeadersWidth = 51; + dataGridView.RowTemplate.Height = 29; + dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; + dataGridView.Size = new Size(640, 455); + dataGridView.TabIndex = 0; + // + // buttonRefresh + // + buttonRefresh.Location = new Point(658, 252); + buttonRefresh.Name = "buttonRefresh"; + buttonRefresh.Size = new Size(120, 40); + buttonRefresh.TabIndex = 12; + buttonRefresh.Text = "Обновить"; + buttonRefresh.UseVisualStyleBackColor = true; + buttonRefresh.Click += ButtonRefresh_Click; + // + // buttonDelete + // + buttonDelete.Location = new Point(658, 183); + buttonDelete.Name = "buttonDelete"; + buttonDelete.Size = new Size(120, 40); + buttonDelete.TabIndex = 11; + buttonDelete.Text = "Удалить"; + buttonDelete.UseVisualStyleBackColor = true; + buttonDelete.Click += ButtonDelete_Click; + // + // buttonUpdate + // + buttonUpdate.Location = new Point(658, 115); + buttonUpdate.Name = "buttonUpdate"; + buttonUpdate.Size = new Size(120, 40); + buttonUpdate.TabIndex = 10; + buttonUpdate.Text = "Изменить"; + buttonUpdate.UseVisualStyleBackColor = true; + buttonUpdate.Click += ButtonUpdate_Click; + // + // buttonAdd + // + buttonAdd.Location = new Point(658, 50); + buttonAdd.Name = "buttonAdd"; + buttonAdd.Size = new Size(120, 40); + buttonAdd.TabIndex = 9; + buttonAdd.Text = "Добавить"; + buttonAdd.UseVisualStyleBackColor = true; + buttonAdd.Click += ButtonAdd_Click; + // + // FormShops + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(buttonRefresh); + Controls.Add(buttonDelete); + Controls.Add(buttonUpdate); + Controls.Add(buttonAdd); + Controls.Add(dataGridView); + Name = "FormShops"; + Text = "Магазины"; + Load += FormShops_Load; + ((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); + ResumeLayout(false); + } + + #endregion + + private DataGridView dataGridView; + private Button buttonRefresh; + private Button buttonDelete; + private Button buttonUpdate; + private Button buttonAdd; + } +} \ No newline at end of file diff --git a/GarmentFactory/FormShops.cs b/GarmentFactory/FormShops.cs new file mode 100644 index 0000000..f8c95d5 --- /dev/null +++ b/GarmentFactory/FormShops.cs @@ -0,0 +1,115 @@ +using GarmentFactory; +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.BusinessLogicsContracts; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace GarmentFactoryView +{ + public partial class FormShops : Form + { + private readonly ILogger _logger; + private readonly IShopLogic _logic; + public FormShops(ILogger logger, IShopLogic logic) + { + InitializeComponent(); + _logger = logger; + _logic = logic; + } + + private void FormShops_Load(object sender, EventArgs e) + { + LoadData(); + } + + private void LoadData() + { + try + { + var list = _logic.ReadList(null); + if (list != null) + { + dataGridView.DataSource = list; + dataGridView.Columns["Id"].Visible = false; + dataGridView.Columns["ShopTextiles"].Visible = false; + dataGridView.Columns["ShopName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + } + _logger.LogInformation("Загрузка магазинов"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки магазинов"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonAdd_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormShop)); + if (service is FormShop form) + { + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } + + private void ButtonUpdate_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + var service = Program.ServiceProvider?.GetService(typeof(FormShop)); + if (service is FormShop form) + { + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } + } + + private void ButtonDelete_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 (!_logic.Delete(new ShopBindingModel + { + Id = id + })) + { + throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка удаления магазина"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } + + private void ButtonRefresh_Click(object sender, EventArgs e) + { + LoadData(); + } + } +} diff --git a/GarmentFactory/FormShops.resx b/GarmentFactory/FormShops.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/GarmentFactory/FormShops.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/GarmentFactory/FormTextiles.Designer.cs b/GarmentFactory/FormTextiles.Designer.cs index 6b41417..a134efe 100644 --- a/GarmentFactory/FormTextiles.Designer.cs +++ b/GarmentFactory/FormTextiles.Designer.cs @@ -38,6 +38,9 @@ // // dataGridView // + dataGridView.AllowUserToAddRows = false; + dataGridView.AllowUserToDeleteRows = false; + dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; dataGridView.Dock = DockStyle.Left; dataGridView.Location = new Point(0, 0); diff --git a/GarmentFactory/Program.cs b/GarmentFactory/Program.cs index fb359df..ab47384 100644 --- a/GarmentFactory/Program.cs +++ b/GarmentFactory/Program.cs @@ -40,11 +40,13 @@ namespace GarmentFactory services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -57,6 +59,12 @@ namespace GarmentFactory services.AddTransient(); services.AddTransient(); services.AddTransient(); + + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + } services.AddTransient(); services.AddTransient(); } diff --git a/GarmentFactoryBusinessLogic/BusinessLogics/OrderLogic.cs b/GarmentFactoryBusinessLogic/BusinessLogics/OrderLogic.cs index d889937..5e53a0d 100644 --- a/GarmentFactoryBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/GarmentFactoryBusinessLogic/BusinessLogics/OrderLogic.cs @@ -19,14 +19,16 @@ namespace GarmentFactoryBusinessLogic.BusinessLogics private readonly ILogger _logger; //Хранение всех заказов private readonly IOrderStorage _orderStorage; - public OrderLogic(ILogger logger, IOrderStorage orderStorage) - { - _logger = logger; - _orderStorage = orderStorage; - } + private readonly IShopStorage _shopStorage; + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IShopStorage shopStorage) + { + _logger = logger; + _orderStorage = orderStorage; + _shopStorage = shopStorage; + } - //Чтение всего списка заказов - public List? ReadList(OrderSearchModel? model) + //Чтение всего списка заказов + public List? ReadList(OrderSearchModel? model) { _logger.LogInformation("ReadList. OrderId:{Id}", model?.Id); var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model); @@ -133,7 +135,18 @@ namespace GarmentFactoryBusinessLogic.BusinessLogics //Перевод заказа в состояние выдачи (окончательное завершение) public bool DeliveryOrder(OrderBindingModel model) { - return ChangeStatus(model, OrderStatus.Выдан); + var order = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); + if (order == null) + { + throw new ArgumentNullException(nameof(order)); + } + + //Если нельзя пополнить магазины таким кол-вом товаров (не хавтает места), то статус не меняем + if (!_shopStorage.RestockShops(new SupplyBindingModel { TextileId = order.TextileId, Count = order.Count })) + { + throw new ArgumentException("Недостаточно места"); + } + return ChangeStatus(model, OrderStatus.Выдан); } } } diff --git a/GarmentFactoryBusinessLogic/ShopLogic.cs b/GarmentFactoryBusinessLogic/ShopLogic.cs new file mode 100644 index 0000000..21ddadf --- /dev/null +++ b/GarmentFactoryBusinessLogic/ShopLogic.cs @@ -0,0 +1,221 @@ +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.BusinessLogicsContracts; +using GarmentFactoryContracts.SearchModels; +using GarmentFactoryContracts.StoragesContracts; +using GarmentFactoryContracts.ViewModels; +using GarmentFactoryDataModels.Models; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryBusinessLogic +{ + public class ShopLogic : IShopLogic + { + private readonly ILogger _logger; + + // Хранилище всех магазинов + private readonly IShopStorage _shopStorage; + + private readonly ITextileStorage _textileStorage; + + public ShopLogic(ILogger logger, IShopStorage shopStorage, ITextileStorage textileStorage) + { + _logger = logger; + _shopStorage = shopStorage; + _textileStorage = textileStorage; + } + + // Чтение конкретного магазина + public ShopViewModel? ReadElement(ShopSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + + _logger.LogInformation("ReadElement. ShopName:{ShopName}. Id:{Id}", model.ShopName, model.Id); + var element = _shopStorage.GetElement(model); + + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + + return null; + } + + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + + return element; + } + + // Чтение всех магазинов + public List? ReadList(ShopSearchModel? model) + { + _logger.LogInformation("ReadList. ShopName:{ShopName}. Id: {Id}", model?.ShopName, model?.Id); + + var list = model == null ? _shopStorage.GetFullList() : _shopStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + // Создание магазина + public bool Create(ShopBindingModel model) + { + CheckModel(model); + + if (_shopStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + // Обновление магазина + public bool Update(ShopBindingModel model) + { + CheckModel(model); + + if (_shopStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + + // Удаление магазина + public bool Delete(ShopBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + + if (_shopStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + + return false; + } + return true; + } + + // Пополнение магазина + public bool MakeSupply(SupplyBindingModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + + if (model.Count <= 0) + { + throw new ArgumentNullException("Количество добавляемых изделий должно быть больше 0"); + } + + var textile = _textileStorage.GetElement(new TextileSearchModel { Id = model.TextileId }); + if (textile == null) + { + throw new ArgumentException($"При добавлении товара в магазин товар с id={model.TextileId} не найден"); + } + + var shop = _shopStorage.GetElement(new ShopSearchModel { Id = model.ShopId }); + if (shop == null) + { + throw new ArgumentException($"При добавлении товара в магазин магазин c id={model.ShopId} не найден"); + } + + int countTextilesInShop = shop.ShopTextiles.Select(x => x.Value.Item2).Sum(); + + //Если в текущий магазин помещается столько товаров + if (countTextilesInShop + model.Count <= shop.TextileMaxCount) + { + // Если такой товар есть, то прибавление переданного кол-ва + if (shop.ShopTextiles.ContainsKey(model.TextileId)) + { + var oldValue = shop.ShopTextiles[model.TextileId]; + oldValue.Item2 += model.Count; + shop.ShopTextiles[model.TextileId] = oldValue; + } + // Если такого товара нет, то кол-во такого товара равно переданному кол-ву + else + { + shop.ShopTextiles.Add(model.TextileId, (textile, model.Count)); + } + + _shopStorage.Update(new() + { + Id = shop.Id, + ShopName = shop.ShopName, + Address = shop.Address, + DateOpen = shop.DateOpen, + ShopTextiles = shop.ShopTextiles, + TextileMaxCount = shop.TextileMaxCount, + }); + return true; + } + //Если не поместилось столько товара + _logger.LogWarning("Required shop is overflowed"); + return false; + } + + // Проверка данных магазина при добавлении/удалении/обновлении + private void CheckModel(ShopBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + + // При удалении проверка дальше не нужна + if (!withParams) + { + return; + } + + // Проверка наличия названия + if (string.IsNullOrEmpty(model.ShopName)) + { + throw new ArgumentNullException("Отсутствует название магазина", nameof(model.ShopName)); + } + + // Проверка наличия адреса + if (string.IsNullOrEmpty(model.Address)) + { + throw new ArgumentNullException("Отсутствует адреса магазина", nameof(model.Address)); + } + + _logger.LogInformation("Shop. ShopName:{ShopName}. Address:{Address}. Id: {Id}", model.ShopName, model.Address, model.Id); + + var element = _shopStorage.GetElement(new ShopSearchModel { ShopName = model.ShopName }); + + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Магазин с таким названием уже есть"); + } + } + + public bool Sell(SupplySearchModel model) + { + if (!model.TextileId.HasValue || !model.Count.HasValue) + { + return false; + } + if (_shopStorage.Sell(model)) + { + _logger.LogInformation("Selling sucsess"); + return true; + } + _logger.LogInformation("Selling failed"); + return false; + } + } +} diff --git a/GarmentFactoryContracts/BindingModels/ShopBindingModel.cs b/GarmentFactoryContracts/BindingModels/ShopBindingModel.cs new file mode 100644 index 0000000..fa5a97f --- /dev/null +++ b/GarmentFactoryContracts/BindingModels/ShopBindingModel.cs @@ -0,0 +1,23 @@ +using GarmentFactoryDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryContracts.BindingModels +{ + public class ShopBindingModel : IShopModel + { + public int Id { get; set; } + public string ShopName { get; set; } = string.Empty; + + public string Address { get; set; } = string.Empty; + + public DateTime DateOpen { get; set; } = DateTime.Now; + + public Dictionary ShopTextiles { get; set; } = new(); + + public int TextileMaxCount { get; set; } + } +} diff --git a/GarmentFactoryContracts/BindingModels/SupplyBindingModel.cs b/GarmentFactoryContracts/BindingModels/SupplyBindingModel.cs new file mode 100644 index 0000000..ba10711 --- /dev/null +++ b/GarmentFactoryContracts/BindingModels/SupplyBindingModel.cs @@ -0,0 +1,16 @@ +using GarmentFactoryDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryContracts.BindingModels +{ + public class SupplyBindingModel : ISupplyModel + { + public int ShopId { get; set; } + public int TextileId { get; set; } + public int Count { get; set; } + } +} diff --git a/GarmentFactoryContracts/BusinessLogicsContracts/IShopLogic.cs b/GarmentFactoryContracts/BusinessLogicsContracts/IShopLogic.cs new file mode 100644 index 0000000..7f43b4d --- /dev/null +++ b/GarmentFactoryContracts/BusinessLogicsContracts/IShopLogic.cs @@ -0,0 +1,29 @@ +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.SearchModels; +using GarmentFactoryContracts.ViewModels; +using GarmentFactoryDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryContracts.BusinessLogicsContracts +{ + public interface IShopLogic + { + List? ReadList(ShopSearchModel? model); + + ShopViewModel? ReadElement(ShopSearchModel model); + + bool Create(ShopBindingModel model); + + bool Update(ShopBindingModel model); + + bool Delete(ShopBindingModel model); + + bool MakeSupply(SupplyBindingModel model); + + bool Sell(SupplySearchModel model); + } +} diff --git a/GarmentFactoryContracts/SearchModels/ShopSearchModel.cs b/GarmentFactoryContracts/SearchModels/ShopSearchModel.cs new file mode 100644 index 0000000..a04e63f --- /dev/null +++ b/GarmentFactoryContracts/SearchModels/ShopSearchModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryContracts.SearchModels +{ + public class ShopSearchModel + { + public int? Id { get; set; } + public string? ShopName { get; set; } + } +} diff --git a/GarmentFactoryContracts/SearchModels/SupplySearchModel.cs b/GarmentFactoryContracts/SearchModels/SupplySearchModel.cs new file mode 100644 index 0000000..360c8a8 --- /dev/null +++ b/GarmentFactoryContracts/SearchModels/SupplySearchModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryContracts.SearchModels +{ + public class SupplySearchModel + { + public int? TextileId { get; set; } + public int? Count { get; set; } + } +} diff --git a/GarmentFactoryContracts/StoragesContracts/IShopStorage.cs b/GarmentFactoryContracts/StoragesContracts/IShopStorage.cs new file mode 100644 index 0000000..1d8cce9 --- /dev/null +++ b/GarmentFactoryContracts/StoragesContracts/IShopStorage.cs @@ -0,0 +1,25 @@ +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.SearchModels; +using GarmentFactoryContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryContracts.StoragesContracts +{ + public interface IShopStorage + { + List GetFullList(); + List GetFilteredList(ShopSearchModel model); + ShopViewModel? GetElement(ShopSearchModel model); + ShopViewModel? Insert(ShopBindingModel model); + ShopViewModel? Update(ShopBindingModel model); + ShopViewModel? Delete(ShopBindingModel model); + //Продажа изделий в нужном кол-ве + bool Sell(SupplySearchModel model); + //Пополнение магаз-ов + bool RestockShops(SupplyBindingModel model); + } +} diff --git a/GarmentFactoryContracts/ViewModels/ShopViewModel.cs b/GarmentFactoryContracts/ViewModels/ShopViewModel.cs new file mode 100644 index 0000000..1853fb6 --- /dev/null +++ b/GarmentFactoryContracts/ViewModels/ShopViewModel.cs @@ -0,0 +1,29 @@ +using GarmentFactoryDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryContracts.ViewModels +{ + public class ShopViewModel : IShopModel + { + public int Id { get; set; } + + [DisplayName("Название магазина")] + public string ShopName { get; set; } = string.Empty; + + [DisplayName("Адрес магазина")] + public string Address { get; set; } = string.Empty; + + [DisplayName("Дата открытия")] + public DateTime DateOpen { get; set; } = DateTime.Now; + + public Dictionary ShopTextiles { get; set; } = new(); + + [DisplayName("Вместимость")] + public int TextileMaxCount { get; set; } + } +} diff --git a/GarmentFactoryDataModels/Models/IShopModel.cs b/GarmentFactoryDataModels/Models/IShopModel.cs new file mode 100644 index 0000000..538079f --- /dev/null +++ b/GarmentFactoryDataModels/Models/IShopModel.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryDataModels.Models +{ + public interface IShopModel : IId + { + string ShopName { get; } + string Address { get; } + DateTime DateOpen { get; } + //Изделия в магазине + Dictionary ShopTextiles { get; } + //макс. кол-во изделий + int TextileMaxCount { get; } + } +} diff --git a/GarmentFactoryDataModels/Models/ISupplyModel.cs b/GarmentFactoryDataModels/Models/ISupplyModel.cs new file mode 100644 index 0000000..88c2137 --- /dev/null +++ b/GarmentFactoryDataModels/Models/ISupplyModel.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryDataModels.Models +{ + //Сущность для связи многие-ко-многим между товарами и магазинами + public class ISupplyModel + { + int ShopId { get; } + int TextileId { get; } + int Count { get; } + } +} diff --git a/GarmentFactoryDatabaseImplement/GarmentFactoryDatabase.cs b/GarmentFactoryDatabaseImplement/GarmentFactoryDatabase.cs index dce2c55..a39000f 100644 --- a/GarmentFactoryDatabaseImplement/GarmentFactoryDatabase.cs +++ b/GarmentFactoryDatabaseImplement/GarmentFactoryDatabase.cs @@ -27,5 +27,9 @@ namespace GarmentFactoryDatabaseImplement public virtual DbSet TextileComponents { set; get; } public virtual DbSet Orders { set; get; } - } + + public virtual DbSet Shops { get; set; } + + public virtual DbSet ShopTextiles { get; set; } + } } diff --git a/GarmentFactoryDatabaseImplement/Implements/ShopStorage.cs b/GarmentFactoryDatabaseImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..23d87c4 --- /dev/null +++ b/GarmentFactoryDatabaseImplement/Implements/ShopStorage.cs @@ -0,0 +1,243 @@ +using GarmentFactoryContracts.SearchModels; +using GarmentFactoryContracts.StoragesContracts; +using GarmentFactoryContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryDatabaseImplement.Models; + +namespace GarmentFactoryDatabaseImplement.Implements +{ + public class ShopStorage : IShopStorage + { + public List GetFullList() + { + using var context = new GarmentFactoryDatabase(); + return context.Shops + .Include(x => x.Textiles) + .ThenInclude(x => x.Textile) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName)) + { + return new(); + } + + using var context = new GarmentFactoryDatabase(); + + return context.Shops + .Include(x => x.Textiles) + .ThenInclude(x => x.Textile) + .Where(x => x.ShopName.Contains(model.ShopName)) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue) + { + return new(); + } + + using var context = new GarmentFactoryDatabase(); + + return context.Shops + .Include(x => x.Textiles) + .ThenInclude(x => x.Textile) + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) && x.ShopName == model.ShopName) + || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + using var context = new GarmentFactoryDatabase(); + + var newShop = Shop.Create(context, model); + if (newShop == null) + { + return null; + } + + context.Shops.Add(newShop); + context.SaveChanges(); + + return newShop.GetViewModel; + } + + public ShopViewModel? Update(ShopBindingModel model) + { + using var context = new GarmentFactoryDatabase(); + + using var transaction = context.Database.BeginTransaction(); + try + { + var shop = context.Shops.FirstOrDefault(x => x.Id == model.Id); + + if (shop == null) + return null; + + shop.Update(model); + context.SaveChanges(); + shop.UpdateTextiles(context, model); + + transaction.Commit(); + return shop.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + + + public ShopViewModel? Delete(ShopBindingModel model) + { + using var context = new GarmentFactoryDatabase(); + var element = context.Shops + .Include(x => x.Textiles) + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Shops.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + //продажа текстиля из магазинов + public bool Sell(SupplySearchModel model) + { + using var context = new GarmentFactoryDatabase(); + using var transaction = context.Database.BeginTransaction(); + + try + { + //поиск всех магаз-ов, в кот. есть нужный текстиль (сортировка: сначала те, где его больше) + var shopsWithThisTextile = context.Shops + .Include(x => x.Textiles) + .ThenInclude(x => x.Textile) + .ToList() + .Where(x => x.ShopTextiles.ContainsKey(model.TextileId.Value)) + .OrderByDescending(x => x.ShopTextiles[model.TextileId.Value].Item2) + .ToList(); + + foreach (var shop in shopsWithThisTextile) + { + //сколько надо будет этого текстиля, если продать все из текущего магазина + int thisTextileNeeded = model.Count.Value - shop.ShopTextiles[model.TextileId.Value].Item2; + + //если ещё надо будет + if (thisTextileNeeded > 0) + { + //полное удаление этого текстиля из этого магазина + shop.ShopTextiles.Remove(model.TextileId.Value); + shop.DictionaryTextilesUpdate(context); + context.SaveChanges(); + + model.Count = thisTextileNeeded; + } + else + { + //если в этом магазине ровно столько, сколько надо + if (thisTextileNeeded == 0) + { + shop.ShopTextiles.Remove(model.TextileId.Value); + } + //если в этом магазине больше, чем надо + else + { + //уменьшение в этом магазине этого текстиля на нужное кол-во + var textileAndCount = shop.ShopTextiles[model.TextileId.Value]; + textileAndCount.Item2 = -thisTextileNeeded; + shop.ShopTextiles[model.TextileId.Value] = textileAndCount; + } + shop.DictionaryTextilesUpdate(context); + transaction.Commit(); + + return true; + } + } + + transaction.Rollback(); + return false; + } + catch + { + transaction.Rollback(); + throw; + } + } + + //пополнение магазинов текстилем + public bool RestockShops(SupplyBindingModel model) + { + using var context = new GarmentFactoryDatabase(); + using var transaction = context.Database.BeginTransaction(); + + //все магазины, где ещё есть свободное место (занятое кол-во < максимально допустимого) + var shops = context.Shops + .Include(x => x.Textiles) + .ThenInclude(x => x.Textile) + .ToList() + .Where(x => x.ShopTextiles.Select(x => x.Value.Item2).Sum() < x.TextileMaxCount) + .ToList(); + + try + { + foreach (Shop shop in shops) + { + //свободное место в этом магазине + int freeSpace = shop.TextileMaxCount - shop.ShopTextiles.Select(x => x.Value.Item2).Sum(); + + //кол-во кот. надо для этого магазина (либо до макс. кол-ва, либо кол-во, кот. осталось в "поставке" (что меньше)) + int restock = Math.Min(freeSpace, model.Count); + model.Count -= restock; + + //если в этом магазине есть этот текстиль, то изменение его кол-ва + if (shop.ShopTextiles.ContainsKey(model.TextileId)) + { + var textileAndCount = shop.ShopTextiles[model.TextileId]; + textileAndCount.Item2 += restock; + shop.ShopTextiles[model.TextileId] = textileAndCount; + } + //если нет, то добавление в этом кол-ве + else + { + var textile = context.Textiles.First(x => x.Id == model.TextileId); + shop.ShopTextiles.Add(model.TextileId, (textile, restock)); + } + + shop.DictionaryTextilesUpdate(context); + + //если в "поставке" закончились товары, то всё ок + if (model.Count == 0) + { + transaction.Commit(); + return true; + } + } + + transaction.Rollback(); + return false; + } + catch + { + transaction.Rollback(); + throw; + } + } + } +} diff --git a/GarmentFactoryDatabaseImplement/Migrations/20240515060701_Lab3_Hard_AddedShops.Designer.cs b/GarmentFactoryDatabaseImplement/Migrations/20240515060701_Lab3_Hard_AddedShops.Designer.cs new file mode 100644 index 0000000..cb61d6b --- /dev/null +++ b/GarmentFactoryDatabaseImplement/Migrations/20240515060701_Lab3_Hard_AddedShops.Designer.cs @@ -0,0 +1,248 @@ +// +using System; +using GarmentFactoryDatabaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GarmentFactoryDatabaseImplement.Migrations +{ + [DbContext(typeof(GarmentFactoryDatabase))] + [Migration("20240515060701_Lab3_Hard_AddedShops")] + partial class Lab3_Hard_AddedShops + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.17") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Cost") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DateComplete") + .HasColumnType("datetime2"); + + b.Property("DateCreate") + .HasColumnType("datetime2"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Sum") + .HasColumnType("float"); + + b.Property("TextileId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TextileId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Shop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DateOpen") + .HasColumnType("datetime2"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TextileMaxCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.ShopTextile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.Property("TextileId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ShopId"); + + b.HasIndex("TextileId"); + + b.ToTable("ShopTextiles"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Price") + .HasColumnType("float"); + + b.Property("TextileName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Textiles"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentId") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("TextileId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ComponentId"); + + b.HasIndex("TextileId"); + + b.ToTable("TextileComponents"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b => + { + b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile") + .WithMany("Orders") + .HasForeignKey("TextileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Textile"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.ShopTextile", b => + { + b.HasOne("GarmentFactoryDatabaseImplement.Models.Shop", "Shop") + .WithMany("Textiles") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile") + .WithMany() + .HasForeignKey("TextileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Shop"); + + b.Navigation("Textile"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b => + { + b.HasOne("GarmentFactoryDatabaseImplement.Models.Component", "Component") + .WithMany("TextileComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile") + .WithMany("Components") + .HasForeignKey("TextileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Component"); + + b.Navigation("Textile"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b => + { + b.Navigation("TextileComponents"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Shop", b => + { + b.Navigation("Textiles"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/GarmentFactoryDatabaseImplement/Migrations/20240515060701_Lab3_Hard_AddedShops.cs b/GarmentFactoryDatabaseImplement/Migrations/20240515060701_Lab3_Hard_AddedShops.cs new file mode 100644 index 0000000..3098a32 --- /dev/null +++ b/GarmentFactoryDatabaseImplement/Migrations/20240515060701_Lab3_Hard_AddedShops.cs @@ -0,0 +1,78 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GarmentFactoryDatabaseImplement.Migrations +{ + /// + public partial class Lab3_Hard_AddedShops : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Shops", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ShopName = table.Column(type: "nvarchar(max)", nullable: false), + Address = table.Column(type: "nvarchar(max)", nullable: false), + DateOpen = table.Column(type: "datetime2", nullable: false), + TextileMaxCount = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Shops", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ShopTextiles", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + TextileId = table.Column(type: "int", nullable: false), + ShopId = table.Column(type: "int", nullable: false), + Count = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ShopTextiles", x => x.Id); + table.ForeignKey( + name: "FK_ShopTextiles_Shops_ShopId", + column: x => x.ShopId, + principalTable: "Shops", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ShopTextiles_Textiles_TextileId", + column: x => x.TextileId, + principalTable: "Textiles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ShopTextiles_ShopId", + table: "ShopTextiles", + column: "ShopId"); + + migrationBuilder.CreateIndex( + name: "IX_ShopTextiles_TextileId", + table: "ShopTextiles", + column: "TextileId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ShopTextiles"); + + migrationBuilder.DropTable( + name: "Shops"); + } + } +} diff --git a/GarmentFactoryDatabaseImplement/Migrations/GarmentFactoryDatabaseModelSnapshot.cs b/GarmentFactoryDatabaseImplement/Migrations/GarmentFactoryDatabaseModelSnapshot.cs index 8547e48..ec9718c 100644 --- a/GarmentFactoryDatabaseImplement/Migrations/GarmentFactoryDatabaseModelSnapshot.cs +++ b/GarmentFactoryDatabaseImplement/Migrations/GarmentFactoryDatabaseModelSnapshot.cs @@ -75,6 +75,59 @@ namespace GarmentFactoryDatabaseImplement.Migrations b.ToTable("Orders"); }); + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Shop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DateOpen") + .HasColumnType("datetime2"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TextileMaxCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.ShopTextile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.Property("TextileId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ShopId"); + + b.HasIndex("TextileId"); + + b.ToTable("ShopTextiles"); + }); + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b => { b.Property("Id") @@ -132,6 +185,25 @@ namespace GarmentFactoryDatabaseImplement.Migrations b.Navigation("Textile"); }); + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.ShopTextile", b => + { + b.HasOne("GarmentFactoryDatabaseImplement.Models.Shop", "Shop") + .WithMany("Textiles") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile") + .WithMany() + .HasForeignKey("TextileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Shop"); + + b.Navigation("Textile"); + }); + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b => { b.HasOne("GarmentFactoryDatabaseImplement.Models.Component", "Component") @@ -156,6 +228,11 @@ namespace GarmentFactoryDatabaseImplement.Migrations b.Navigation("TextileComponents"); }); + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Shop", b => + { + b.Navigation("Textiles"); + }); + modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b => { b.Navigation("Components"); diff --git a/GarmentFactoryDatabaseImplement/Models/Shop.cs b/GarmentFactoryDatabaseImplement/Models/Shop.cs new file mode 100644 index 0000000..501a50f --- /dev/null +++ b/GarmentFactoryDatabaseImplement/Models/Shop.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using GarmentFactoryDataModels.Models; +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.ViewModels; + +namespace GarmentFactoryDatabaseImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; set; } + + [Required] + public string ShopName { get; set; } = string.Empty; + + [Required] + public string Address { get; set; } = string.Empty; + + [Required] + public DateTime DateOpen { get; set; } + + [Required] + public int TextileMaxCount { get; set; } + + [ForeignKey("ShopId")] + public List Textiles { get; set; } = new(); + + private Dictionary? _shopTextiles = null; + + [NotMapped] + public Dictionary ShopTextiles + { + get + { + if (_shopTextiles == null) + { + if (_shopTextiles == null) + { + _shopTextiles = Textiles.ToDictionary(x => x.TextileId, y => (y.Textile as ITextileModel, y.Count)); + } + return _shopTextiles; + } + + return _shopTextiles; + } + } + + public static Shop Create(GarmentFactoryDatabase context, ShopBindingModel model) + { + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOpen = model.DateOpen, + TextileMaxCount = model.TextileMaxCount, + Textiles = model.ShopTextiles.Select(x => new ShopTextile + { + Textile = context.Textiles.First(y => y.Id == x.Key), + Count = x.Value.Item2 + }).ToList(), + }; + } + + public void Update(ShopBindingModel model) + { + ShopName = model.ShopName; + Address = model.Address; + DateOpen = model.DateOpen; + TextileMaxCount = model.TextileMaxCount; + } + + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpen = DateOpen, + ShopTextiles = ShopTextiles, + TextileMaxCount = TextileMaxCount + }; + + public void UpdateTextiles(GarmentFactoryDatabase context, ShopBindingModel model) + { + var ShopTextiles = context.ShopTextiles + .Where(rec => rec.ShopId == model.Id) + .ToList(); + + if (ShopTextiles != null && ShopTextiles.Count > 0) + { + context.ShopTextiles.RemoveRange(ShopTextiles.Where(rec => !model.ShopTextiles.ContainsKey(rec.TextileId))); + context.SaveChanges(); + + ShopTextiles = context.ShopTextiles.Where(rec => rec.ShopId == model.Id).ToList(); + + foreach (var textileToUpdate in ShopTextiles) + { + textileToUpdate.Count = model.ShopTextiles[textileToUpdate.TextileId].Item2; + model.ShopTextiles.Remove(textileToUpdate.TextileId); + } + + context.SaveChanges(); + } + + var Shop = context.Shops.First(x => x.Id == Id); + + foreach (var ShopTextile in model.ShopTextiles) + { + context.ShopTextiles.Add(new ShopTextile + { + Shop = Shop, + Textile = context.Textiles.First(x => x.Id == ShopTextile.Key), + Count = ShopTextile.Value.Item2 + }); + + context.SaveChanges(); + } + + _shopTextiles = null; + } + + public void DictionaryTextilesUpdate(GarmentFactoryDatabase context) + { + UpdateTextiles(context, new ShopBindingModel + { + Id = Id, + ShopTextiles = ShopTextiles + }); + } + } +} diff --git a/GarmentFactoryDatabaseImplement/Models/ShopTextile.cs b/GarmentFactoryDatabaseImplement/Models/ShopTextile.cs new file mode 100644 index 0000000..c4985b6 --- /dev/null +++ b/GarmentFactoryDatabaseImplement/Models/ShopTextile.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryDatabaseImplement.Models +{ + public class ShopTextile + { + public int Id { get; set; } + + [Required] + public int TextileId { get; set; } + + [Required] + public int ShopId { get; set; } + + [Required] + public int Count { get; set; } + + public virtual Shop Shop { get; set; } = new(); + + public virtual Textile Textile { get; set; } = new(); + } +} diff --git a/GarmentFactoryFileImplement/DataFileSingleton.cs b/GarmentFactoryFileImplement/DataFileSingleton.cs index a15d72e..90c144d 100644 --- a/GarmentFactoryFileImplement/DataFileSingleton.cs +++ b/GarmentFactoryFileImplement/DataFileSingleton.cs @@ -14,10 +14,12 @@ namespace GarmentFactoryFileImplement private readonly string ComponentFileName = "Component.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string TextileFileName = "Textile.xml"; - public List Components { get; private set; } + private readonly string ShopFileName = "Shop.xml"; + public List Components { get; private set; } public List Orders { get; private set; } public List Textiles { get; private set; } - public static DataFileSingleton GetInstance() + public List Shops { get; private set; } + public static DataFileSingleton GetInstance() { if (instance == null) { @@ -28,13 +30,14 @@ namespace GarmentFactoryFileImplement public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); public void SaveTextiles() => SaveData(Textiles, TextileFileName, "Textiles", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); - - private DataFileSingleton() + public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", x => x.GetXElement); + private DataFileSingleton() { Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!; Textiles = LoadData(TextileFileName, "Textile", x => Textile.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; - } + Shops = LoadData(ShopFileName, "Shop", x => Shop.Create(x)!)!; + } private static List? LoadData(string filename, string xmlNodeName, Func selectFunction) { diff --git a/GarmentFactoryFileImplement/Implements/ShopStorage.cs b/GarmentFactoryFileImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..e30ebbd --- /dev/null +++ b/GarmentFactoryFileImplement/Implements/ShopStorage.cs @@ -0,0 +1,183 @@ +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.SearchModels; +using GarmentFactoryContracts.StoragesContracts; +using GarmentFactoryContracts.ViewModels; +using GarmentFactoryFileImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryFileImplement.Implements +{ + public class ShopStorage : IShopStorage + { + private readonly DataFileSingleton source; + + public ShopStorage() + { + source = DataFileSingleton.GetInstance(); + } + + public List GetFullList() + { + return source.Shops.Select(x => x.GetViewModel).ToList(); + } + + public List GetFilteredList(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName)) + { + return new(); + } + return source.Shops.Where(x => x.ShopName.Contains(model.ShopName)).Select(x => x.GetViewModel).ToList(); + } + + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue) + { + return null; + } + return source.Shops.FirstOrDefault(x => + (!string.IsNullOrEmpty(model.ShopName) && x.ShopName == model.ShopName) || + (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + model.Id = source.Shops.Count > 0 ? source.Shops.Max(x => x.Id) + 1 : 1; + var newShop = Shop.Create(model); + if (newShop == null) + { + return null; + } + source.Shops.Add(newShop); + source.SaveShops(); + return newShop.GetViewModel; + } + + public ShopViewModel? Update(ShopBindingModel model) + { + var shop = source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (shop == null) + { + return null; + } + shop.Update(model); + source.SaveShops(); + return shop.GetViewModel; + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + var shop = source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (shop != null) + { + source.Shops.Remove(shop); + source.SaveShops(); + return shop.GetViewModel; + } + return null; + } + + public bool Sell(SupplySearchModel model) + { + if (model == null || !model.TextileId.HasValue || !model.Count.HasValue) + { + return false; + } + + //магазины по степени наполненности (от самого наполненного) с этим текстилем + var shopsWithThisTextile = source.Shops.Where(x => x.Textiles.ContainsKey(model.TextileId.Value)).OrderByDescending(x => x.Textiles[model.TextileId.Value]).ToList(); + + int thisTextileInShops = shopsWithThisTextile.Select(x => x.Textiles[model.TextileId.Value]).Sum(); + + if (thisTextileInShops < model.Count) + { + return false; + } + + foreach (var shop in shopsWithThisTextile) + { + //кол-во необходимых текстилей после возможной продажи всех текстилей + int thisTextileNeed = model.Count.Value - shop.Textiles[model.TextileId.Value]; + + //Если текстиль ещё нужен будет + if (thisTextileNeed > 0) + { + //удаление всех текстилей в этом магазине + shop.Textiles.Remove(model.TextileId.Value); + shop.TextilesUpdate(); + model.Count = thisTextileNeed; + } + + else + { + //Если ровно хватает + if (thisTextileNeed == 0) + { + shop.Textiles.Remove(model.TextileId.Value); + } + //Если нужно меньше, чем есть в магазине + else + { + //уменьшение кол-ва + shop.Textiles[model.TextileId.Value] = -thisTextileNeed; + } + shop.TextilesUpdate(); + source.SaveShops(); + return true; + } + } + source.SaveShops(); + return false; + } + + public bool RestockShops(SupplyBindingModel model) + { + //подсчёт свободных мест через сумму свободных мест в каждом магазине + //в каждом магазине кол-во свободных мест = макс. кол-во - занятые места + int totalFreeSpace = source.Shops + .Select(x => x.TextileMaxCount - x.ShopTextiles.Select(y => y.Value.Item2).Sum()) + .Sum(); + + //если места не хватает + if (totalFreeSpace < model.Count) + { + return false; + } + + var shopsWithFreeSpace = source.Shops.Where(x => x.TextileMaxCount - x.ShopTextiles.Select(x => x.Value.Item2).Sum() > 0); + + foreach (Shop shop in shopsWithFreeSpace) + { + int freeSpace = shop.TextileMaxCount - shop.ShopTextiles.Select(x => x.Value.Item2).Sum(); + + freeSpace = Math.Min(freeSpace, model.Count); + model.Count -= freeSpace; + + if (shop.Textiles.ContainsKey(model.TextileId)) + { + shop.Textiles[model.TextileId] += freeSpace; + } + + else + { + shop.Textiles.Add(model.TextileId, freeSpace); + } + + shop.TextilesUpdate(); + + if (model.Count == 0) + { + source.SaveShops(); + return true; + } + } + return false; + } + } +} diff --git a/GarmentFactoryFileImplement/Models/Shop.cs b/GarmentFactoryFileImplement/Models/Shop.cs new file mode 100644 index 0000000..27f7010 --- /dev/null +++ b/GarmentFactoryFileImplement/Models/Shop.cs @@ -0,0 +1,111 @@ +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.ViewModels; +using GarmentFactoryDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace GarmentFactoryFileImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + public string ShopName { get; private set; } = string.Empty; + public string Address { get; private set; } = string.Empty; + public DateTime DateOpen { get; private set; } + public Dictionary Textiles { get; private set; } = new(); + private Dictionary? _shopTextiles = null; + + public Dictionary ShopTextiles + { + get + { + if (_shopTextiles == null) + { + var source = DataFileSingleton.GetInstance(); + _shopTextiles = Textiles.ToDictionary(x => x.Key, y => ((source.Textiles.FirstOrDefault(z => z.Id == y.Key) as ITextileModel)!, y.Value)); + } + return _shopTextiles; + } + } + + public int TextileMaxCount { get; private set; } + + public static Shop? Create(ShopBindingModel? model) + { + if (model == null) + { + return null; + } + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOpen = model.DateOpen, + Textiles = model.ShopTextiles.ToDictionary(x => x.Key, x => x.Value.Item2), + TextileMaxCount = model.TextileMaxCount + }; + } + + public static Shop? Create(XElement element) + { + if (element == null) + { + return null; + } + return new() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ShopName = element.Element("ShopName")!.Value, + Address = element.Element("Address")!.Value, + DateOpen = Convert.ToDateTime(element.Element("DateOpen")!.Value), + Textiles = element.Element("ShopTextiles")!.Elements("ShopTextile")!.ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value), + x => Convert.ToInt32(x.Element("Value")?.Value)), + TextileMaxCount = Convert.ToInt32(element.Element("TextileMaxCount")!.Value) + }; + } + + public void Update(ShopBindingModel? model) + { + if (model == null) + { + return; + } + ShopName = model.ShopName; + Address = model.Address; + DateOpen = model.DateOpen; + TextileMaxCount = model.TextileMaxCount; + Textiles = model.ShopTextiles.ToDictionary(x => x.Key, x => x.Value.Item2); + _shopTextiles = null; + } + + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpen = DateOpen, + ShopTextiles = ShopTextiles, + TextileMaxCount = TextileMaxCount + }; + + public XElement GetXElement => new("Shop", + new XAttribute("Id", Id), + new XElement("ShopName", ShopName), + new XElement("Address", Address), + new XElement("DateOpen", DateOpen.ToString()), + new XElement("ShopTextiles", Textiles.Select( + x => new XElement("ShopTextile", new XElement("Key", x.Key), new XElement("Value", x.Value))).ToArray()), + new XElement("TextileMaxCount", TextileMaxCount.ToString()) + ); + + public void TextilesUpdate() + { + _shopTextiles = null; + } + } +} diff --git a/GarmentFactoryListImplement/DataListSingleton.cs b/GarmentFactoryListImplement/DataListSingleton.cs index 2ae53af..a3e0efb 100644 --- a/GarmentFactoryListImplement/DataListSingleton.cs +++ b/GarmentFactoryListImplement/DataListSingleton.cs @@ -8,11 +8,13 @@ namespace GarmentFactoryListImplement public List Components { get; set; } public List Orders { get; set; } public List Textiles { get; set; } + public List Shops { get; set; } private DataListSingleton() { Components = new List(); Orders = new List(); Textiles = new List(); + Shops = new List(); } public static DataListSingleton GetInstance() { diff --git a/GarmentFactoryListImplement/Implements/ShopStorage.cs b/GarmentFactoryListImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..d28bf04 --- /dev/null +++ b/GarmentFactoryListImplement/Implements/ShopStorage.cs @@ -0,0 +1,124 @@ +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.SearchModels; +using GarmentFactoryContracts.StoragesContracts; +using GarmentFactoryContracts.ViewModels; +using GarmentFactoryDataModels.Models; +using GarmentFactoryListImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryListImplement.Implements +{ + public class ShopStorage : IShopStorage + { + private readonly DataListSingleton _source; + + public ShopStorage() + { + _source = DataListSingleton.GetInstance(); + } + + public List GetFullList() + { + var result = new List(); + foreach (var shop in _source.Shops) + { + result.Add(shop.GetViewModel); + } + return result; + } + + public List GetFilteredList(ShopSearchModel model) + { + var result = new List(); + if (string.IsNullOrEmpty(model.ShopName)) + { + return result; + } + foreach (var shop in _source.Shops) + { + if (shop.ShopName.Contains(model.ShopName)) + { + result.Add(shop.GetViewModel); + } + } + return result; + } + + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue) + { + return null; + } + foreach (var shop in _source.Shops) + { + if ((!string.IsNullOrEmpty(model.ShopName) && shop.ShopName == model.ShopName) || + (model.Id.HasValue && shop.Id == model.Id)) + { + return shop.GetViewModel; + } + } + return null; + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + model.Id = 1; + foreach (var shop in _source.Shops) + { + if (model.Id <= shop.Id) + { + model.Id = shop.Id + 1; + } + } + var newShop = Shop.Create(model); + if (newShop == null) + { + return null; + } + _source.Shops.Add(newShop); + return newShop.GetViewModel; + } + + public ShopViewModel? Update(ShopBindingModel model) + { + foreach (var shop in _source.Shops) + { + if (shop.Id == model.Id) + { + shop.Update(model); + return shop.GetViewModel; + } + } + return null; + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + for (int i = 0; i < _source.Shops.Count; ++i) + { + if (_source.Shops[i].Id == model.Id) + { + var element = _source.Shops[i]; + _source.Shops.RemoveAt(i); + return element.GetViewModel; + } + } + return null; + } + + public bool Sell(SupplySearchModel model) + { + throw new NotImplementedException(); + } + + public bool RestockShops(SupplyBindingModel model) + { + throw new NotImplementedException(); + } + } +} diff --git a/GarmentFactoryListImplement/Models/Shop.cs b/GarmentFactoryListImplement/Models/Shop.cs new file mode 100644 index 0000000..34f85e3 --- /dev/null +++ b/GarmentFactoryListImplement/Models/Shop.cs @@ -0,0 +1,66 @@ +using GarmentFactoryContracts.BindingModels; +using GarmentFactoryContracts.ViewModels; +using GarmentFactoryDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GarmentFactoryListImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + public string ShopName { get; private set; } = string.Empty; + + public string Address { get; private set; } = string.Empty; + + public DateTime DateOpen { get; private set; } + + public Dictionary ShopTextiles { get; private set; } = new(); + + public int TextileMaxCount { get; private set; } + + + public static Shop? Create(ShopBindingModel? model) + { + if (model == null) + { + return null; + } + + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOpen = model.DateOpen, + ShopTextiles = model.ShopTextiles, + TextileMaxCount = model.TextileMaxCount + }; + } + public void Update(ShopBindingModel? model) + { + if (model == null) + { + return; + } + ShopName = model.ShopName; + Address = model.Address; + DateOpen = model.DateOpen; + ShopTextiles = model.ShopTextiles; + TextileMaxCount = model.TextileMaxCount; + + } + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpen = DateOpen, + ShopTextiles = ShopTextiles, + TextileMaxCount = TextileMaxCount + }; + } +}