diff --git a/SushiBar/FormMain.Designer.cs b/SushiBar/FormMain.Designer.cs index 98864c7..b3ba388 100644 --- a/SushiBar/FormMain.Designer.cs +++ b/SushiBar/FormMain.Designer.cs @@ -36,12 +36,15 @@ списокКомпонентовToolStripMenuItem = new ToolStripMenuItem(); компонентыПоИзделиямToolStripMenuItem = new ToolStripMenuItem(); списокЗаказовToolStripMenuItem = new ToolStripMenuItem(); + магазиныToolStripMenuItem = new ToolStripMenuItem(); dataGridView = new DataGridView(); buttonCreateOrder = new Button(); buttonTakeOrderInWork = new Button(); buttonOrderReady = new Button(); buttonOrderIssued = new Button(); buttonRefreshOrders = new Button(); + buttonAddSushiInShop = new Button(); + buttonSelling = new Button(); menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); SuspendLayout(); @@ -58,7 +61,7 @@ // // ToolStripMenuItemRef // - ToolStripMenuItemRef.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, сушиToolStripMenuItem }); + ToolStripMenuItemRef.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, сушиToolStripMenuItem, магазиныToolStripMenuItem }); ToolStripMenuItemRef.Name = "ToolStripMenuItemRef"; ToolStripMenuItemRef.Size = new Size(117, 24); ToolStripMenuItemRef.Text = "Справочники"; @@ -105,6 +108,13 @@ списокЗаказовToolStripMenuItem.Text = "Список заказов"; списокЗаказовToolStripMenuItem.Click += списокЗаказовToolStripMenuItem_Click; // + // магазиныToolStripMenuItem + // + магазиныToolStripMenuItem.Name = "магазиныToolStripMenuItem"; + магазиныToolStripMenuItem.Size = new Size(182, 26); + магазиныToolStripMenuItem.Text = "Магазины"; + магазиныToolStripMenuItem.Click += магазиныToolStripMenuItem_Click; + // // dataGridView // dataGridView.BackgroundColor = Color.White; @@ -119,7 +129,7 @@ // // buttonCreateOrder // - buttonCreateOrder.Location = new Point(923, 63); + buttonCreateOrder.Location = new Point(923, 43); buttonCreateOrder.Name = "buttonCreateOrder"; buttonCreateOrder.Size = new Size(171, 52); buttonCreateOrder.TabIndex = 2; @@ -129,7 +139,7 @@ // // buttonTakeOrderInWork // - buttonTakeOrderInWork.Location = new Point(923, 161); + buttonTakeOrderInWork.Location = new Point(923, 118); buttonTakeOrderInWork.Name = "buttonTakeOrderInWork"; buttonTakeOrderInWork.Size = new Size(171, 52); buttonTakeOrderInWork.TabIndex = 3; @@ -139,7 +149,7 @@ // // buttonOrderReady // - buttonOrderReady.Location = new Point(923, 253); + buttonOrderReady.Location = new Point(923, 191); buttonOrderReady.Name = "buttonOrderReady"; buttonOrderReady.Size = new Size(171, 52); buttonOrderReady.TabIndex = 4; @@ -149,7 +159,7 @@ // // buttonOrderIssued // - buttonOrderIssued.Location = new Point(923, 351); + buttonOrderIssued.Location = new Point(923, 264); buttonOrderIssued.Name = "buttonOrderIssued"; buttonOrderIssued.Size = new Size(171, 52); buttonOrderIssued.TabIndex = 5; @@ -159,7 +169,7 @@ // // buttonRefreshOrders // - buttonRefreshOrders.Location = new Point(923, 450); + buttonRefreshOrders.Location = new Point(923, 476); buttonRefreshOrders.Name = "buttonRefreshOrders"; buttonRefreshOrders.Size = new Size(171, 52); buttonRefreshOrders.TabIndex = 6; @@ -167,12 +177,34 @@ buttonRefreshOrders.UseVisualStyleBackColor = true; buttonRefreshOrders.Click += ButtonRef_Click; // + // buttonAddSushiInShop + // + buttonAddSushiInShop.Location = new Point(923, 333); + buttonAddSushiInShop.Name = "buttonAddSushiInShop"; + buttonAddSushiInShop.Size = new Size(171, 52); + buttonAddSushiInShop.TabIndex = 7; + buttonAddSushiInShop.Text = "Пополнить магазин"; + buttonAddSushiInShop.UseVisualStyleBackColor = true; + buttonAddSushiInShop.Click += buttonAddSushiInShop_Click; + // + // buttonSelling + // + buttonSelling.Location = new Point(923, 404); + buttonSelling.Name = "buttonSelling"; + buttonSelling.Size = new Size(171, 52); + buttonSelling.TabIndex = 8; + buttonSelling.Text = "Продать суши"; + buttonSelling.UseVisualStyleBackColor = true; + buttonSelling.Click += buttonSelling_Click; + // // FormMain // AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; BackColor = Color.FromArgb(210, 255, 210); ClientSize = new Size(1140, 540); + Controls.Add(buttonSelling); + Controls.Add(buttonAddSushiInShop); Controls.Add(buttonRefreshOrders); Controls.Add(buttonOrderIssued); Controls.Add(buttonOrderReady); @@ -203,6 +235,9 @@ private Button buttonRefreshOrders; private ToolStripMenuItem компонентыToolStripMenuItem; private ToolStripMenuItem сушиToolStripMenuItem; + private ToolStripMenuItem магазиныToolStripMenuItem; + private Button buttonAddSushiInShop; + private Button buttonSelling; private ToolStripMenuItem отчетыToolStripMenuItem; private ToolStripMenuItem списокКомпонентовToolStripMenuItem; private ToolStripMenuItem компонентыПоИзделиямToolStripMenuItem; diff --git a/SushiBar/FormMain.cs b/SushiBar/FormMain.cs index 254d871..4f7f14d 100644 --- a/SushiBar/FormMain.cs +++ b/SushiBar/FormMain.cs @@ -2,6 +2,7 @@ using SushiBar; using SushiBarContracts.BindingModel; using SushiBarContracts.BusinessLogicsContracts; +using SushiBarView.Shops; using SushiBarView.Reports; namespace SushiBarView @@ -58,6 +59,12 @@ namespace SushiBarView if (service is FormSushis formSushis) { formSushis.ShowDialog(); } } + private void магазиныToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormShops)); + if (service is FormShops formShops) { formShops.ShowDialog(); } + } + private void buttonCreateOrder_Click(object sender, EventArgs e) { var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); @@ -99,7 +106,7 @@ namespace SushiBarView _logger.LogInformation("Заказ ${id}. Меняется статус на 'Готов'", id); try { - var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id }); + var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id, }); if (!operationResult) { throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); @@ -156,6 +163,23 @@ namespace SushiBarView } } + private void buttonAddSushiInShop_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormAddSushiInShop)); + if (service is FormAddSushiInShop form) + { + form.ShowDialog(); + } + } + + private void buttonSelling_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormSell)); + if (service is FormSell form) + { + form.ShowDialog(); + } + } private void компонентыПоИзделиямToolStripMenuItem_Click(object sender, EventArgs e) { var service = Program.ServiceProvider?.GetService(typeof(FormReportSushiComponent)); diff --git a/SushiBar/Program.cs b/SushiBar/Program.cs index cd9022b..8c22581 100644 --- a/SushiBar/Program.cs +++ b/SushiBar/Program.cs @@ -9,6 +9,7 @@ using SushiBarContracts.BusinessLogicsContracts; using SushiBarContracts.StoragesContracts; using SushiBarDatabaseImplement.Implements; using SushiBarView; +using SushiBarView.Shops; using SushiBarView.Reports; using System.Text; @@ -48,10 +49,13 @@ namespace SushiBar services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddTransient(); @@ -68,6 +72,10 @@ namespace SushiBar services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file diff --git a/SushiBar/Shops/FormAddSushiInShop.Designer.cs b/SushiBar/Shops/FormAddSushiInShop.Designer.cs new file mode 100644 index 0000000..f0ab7a5 --- /dev/null +++ b/SushiBar/Shops/FormAddSushiInShop.Designer.cs @@ -0,0 +1,149 @@ +namespace SushiBarView.Shops +{ + partial class FormAddSushiInShop + { + /// + /// 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() + { + comboBoxSushi = new ComboBox(); + labelSushi = new Label(); + labelShop = new Label(); + comboBoxShop = new ComboBox(); + textBoxCount = new TextBox(); + labelCount = new Label(); + buttonSave = new Button(); + buttonCancel = new Button(); + SuspendLayout(); + // + // comboBoxSushi + // + comboBoxSushi.FormattingEnabled = true; + comboBoxSushi.Location = new Point(212, 49); + comboBoxSushi.Margin = new Padding(4); + comboBoxSushi.Name = "comboBoxSushi"; + comboBoxSushi.Size = new Size(188, 30); + comboBoxSushi.TabIndex = 0; + // + // labelSushi + // + labelSushi.AutoSize = true; + labelSushi.Location = new Point(42, 57); + labelSushi.Margin = new Padding(4, 0, 4, 0); + labelSushi.Name = "labelSushi"; + labelSushi.Size = new Size(60, 22); + labelSushi.TabIndex = 1; + labelSushi.Text = "Суши: "; + // + // labelShop + // + labelShop.AutoSize = true; + labelShop.Location = new Point(42, 188); + labelShop.Margin = new Padding(4, 0, 4, 0); + labelShop.Name = "labelShop"; + labelShop.Size = new Size(86, 22); + labelShop.TabIndex = 3; + labelShop.Text = "Магазин: "; + // + // comboBoxShop + // + comboBoxShop.FormattingEnabled = true; + comboBoxShop.Location = new Point(212, 188); + comboBoxShop.Margin = new Padding(4); + comboBoxShop.Name = "comboBoxShop"; + comboBoxShop.Size = new Size(188, 30); + comboBoxShop.TabIndex = 2; + // + // textBoxCount + // + textBoxCount.Location = new Point(212, 118); + textBoxCount.Name = "textBoxCount"; + textBoxCount.Size = new Size(188, 29); + textBoxCount.TabIndex = 4; + // + // labelCount + // + labelCount.AutoSize = true; + labelCount.Location = new Point(42, 121); + labelCount.Margin = new Padding(4, 0, 4, 0); + labelCount.Name = "labelCount"; + labelCount.Size = new Size(154, 22); + labelCount.TabIndex = 5; + labelCount.Text = "Количество суши: "; + // + // buttonSave + // + buttonSave.Location = new Point(471, 174); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(107, 44); + buttonSave.TabIndex = 6; + buttonSave.Text = "Сохранить"; + buttonSave.UseVisualStyleBackColor = true; + buttonSave.Click += buttonSave_Click; + // + // buttonCancel + // + buttonCancel.Location = new Point(617, 174); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(107, 44); + buttonCancel.TabIndex = 7; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += buttonCancel_Click; + // + // FormAddSushiInShop + // + AutoScaleDimensions = new SizeF(10F, 22F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(762, 267); + Controls.Add(buttonCancel); + Controls.Add(buttonSave); + Controls.Add(labelCount); + Controls.Add(textBoxCount); + Controls.Add(labelShop); + Controls.Add(comboBoxShop); + Controls.Add(labelSushi); + Controls.Add(comboBoxSushi); + Font = new Font("Candara", 10.8F, FontStyle.Regular, GraphicsUnit.Point, 204); + Margin = new Padding(4); + Name = "FormAddSushiInShop"; + Text = "Пополняем магазинчик"; + Load += FormAddSushiInShop_Load; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private ComboBox comboBoxSushi; + private Label labelSushi; + private Label labelShop; + private ComboBox comboBoxShop; + private TextBox textBoxCount; + private Label labelCount; + private Button buttonSave; + private Button buttonCancel; + } +} \ No newline at end of file diff --git a/SushiBar/Shops/FormAddSushiInShop.cs b/SushiBar/Shops/FormAddSushiInShop.cs new file mode 100644 index 0000000..77f0d3a --- /dev/null +++ b/SushiBar/Shops/FormAddSushiInShop.cs @@ -0,0 +1,114 @@ +using Microsoft.Extensions.Logging; +using SushiBarContracts.BindingModel; +using SushiBarContracts.BusinessLogicsContracts; +using SushiBarContracts.SearchModel; + +namespace SushiBarView.Shops +{ + public partial class FormAddSushiInShop : Form + { + private readonly ILogger _logger; + private readonly IShopLogic _shopLogic; + private readonly ISushiLogic _sushiLogic; + + public FormAddSushiInShop(ILogger logger, IShopLogic shopLogic, ISushiLogic sushiLogic) + { + InitializeComponent(); + _logger = logger; + _shopLogic = shopLogic; + _sushiLogic = sushiLogic; + } + + private void buttonSave_Click(object sender, EventArgs e) + { + if (comboBoxShop.SelectedValue == null) + { + MessageBox.Show("Выберите магазин", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (comboBoxSushi.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 = _shopLogic.AddSushiInShop( + new ShopSearchModel { Id = Convert.ToInt32(comboBoxShop.SelectedValue), ShopName = comboBoxShop.Text }, + new SushiBindingModel { Id = Convert.ToInt32(comboBoxSushi.SelectedValue), SushiName = comboBoxSushi.Text }, + Convert.ToInt32(textBoxCount.Text) + ); + + if (!operationResult) + { + MessageBox.Show("Не получилось почему-то добавить суши", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + 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 FormAddSushiInShop_Load(object sender, EventArgs e) + { + _logger.LogInformation("Загрузка магазинов"); + try + { + var listShops = _shopLogic.ReadList(null); + if (listShops != null) + { + comboBoxShop.DisplayMember = "ShopName"; + comboBoxShop.ValueMember = "Id"; + comboBoxShop.DataSource = listShops; + comboBoxShop.SelectedItem = null; + } + + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки списка магазинов"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + _logger.LogInformation("Загрузка суши"); + try + { + var list = _sushiLogic.ReadList(null); + if (list != null) + { + comboBoxSushi.DisplayMember = "SushiName"; + comboBoxSushi.ValueMember = "Id"; + comboBoxSushi.DataSource = list; + comboBoxSushi.SelectedItem = null; + } + + } + 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/SushiBar/Shops/FormAddSushiInShop.resx b/SushiBar/Shops/FormAddSushiInShop.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/SushiBar/Shops/FormAddSushiInShop.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/SushiBar/Shops/FormSell.Designer.cs b/SushiBar/Shops/FormSell.Designer.cs new file mode 100644 index 0000000..b690675 --- /dev/null +++ b/SushiBar/Shops/FormSell.Designer.cs @@ -0,0 +1,128 @@ +namespace SushiBarView.Shops +{ + partial class FormSell + { + /// + /// 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() + { + comboBoxSushis = new ComboBox(); + labelSushi = new Label(); + numericUpDownCountForSelling = new NumericUpDown(); + labelCountForSelling = new Label(); + buttonSell = new Button(); + buttonCancel = new Button(); + ((System.ComponentModel.ISupportInitialize)numericUpDownCountForSelling).BeginInit(); + SuspendLayout(); + // + // comboBoxSushis + // + comboBoxSushis.FormattingEnabled = true; + comboBoxSushis.Location = new Point(342, 41); + comboBoxSushis.Margin = new Padding(4); + comboBoxSushis.Name = "comboBoxSushis"; + comboBoxSushis.Size = new Size(206, 32); + comboBoxSushis.TabIndex = 0; + // + // labelSushi + // + labelSushi.AutoSize = true; + labelSushi.Location = new Point(45, 50); + labelSushi.Margin = new Padding(4, 0, 4, 0); + labelSushi.Name = "labelSushi"; + labelSushi.Size = new Size(56, 24); + labelSushi.TabIndex = 1; + labelSushi.Text = "Суши"; + // + // numericUpDownCountForSelling + // + numericUpDownCountForSelling.Location = new Point(342, 124); + numericUpDownCountForSelling.Margin = new Padding(4); + numericUpDownCountForSelling.Name = "numericUpDownCountForSelling"; + numericUpDownCountForSelling.Size = new Size(208, 32); + numericUpDownCountForSelling.TabIndex = 2; + // + // labelCountForSelling + // + labelCountForSelling.AutoSize = true; + labelCountForSelling.Location = new Point(45, 126); + labelCountForSelling.Margin = new Padding(4, 0, 4, 0); + labelCountForSelling.Name = "labelCountForSelling"; + labelCountForSelling.Size = new Size(229, 24); + labelCountForSelling.TabIndex = 3; + labelCountForSelling.Text = "Количество для продажи"; + // + // buttonSell + // + buttonSell.Location = new Point(60, 259); + buttonSell.Name = "buttonSell"; + buttonSell.Size = new Size(135, 51); + buttonSell.TabIndex = 4; + buttonSell.Text = "Продать"; + buttonSell.UseVisualStyleBackColor = true; + buttonSell.Click += buttonSell_Click; + // + // buttonCancel + // + buttonCancel.Location = new Point(515, 259); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(160, 51); + buttonCancel.TabIndex = 5; + buttonCancel.Text = "Не продавать "; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += buttonCancel_Click; + // + // FormSell + // + AutoScaleDimensions = new SizeF(11F, 24F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = Color.RosyBrown; + ClientSize = new Size(716, 369); + Controls.Add(buttonCancel); + Controls.Add(buttonSell); + Controls.Add(labelCountForSelling); + Controls.Add(numericUpDownCountForSelling); + Controls.Add(labelSushi); + Controls.Add(comboBoxSushis); + Font = new Font("Candara", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); + Margin = new Padding(4); + Name = "FormSell"; + Text = "Продажа суши"; + Load += FormSell_Load; + ((System.ComponentModel.ISupportInitialize)numericUpDownCountForSelling).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private ComboBox comboBoxSushis; + private Label labelSushi; + private NumericUpDown numericUpDownCountForSelling; + private Label labelCountForSelling; + private Button buttonSell; + private Button buttonCancel; + } +} \ No newline at end of file diff --git a/SushiBar/Shops/FormSell.cs b/SushiBar/Shops/FormSell.cs new file mode 100644 index 0000000..d804386 --- /dev/null +++ b/SushiBar/Shops/FormSell.cs @@ -0,0 +1,89 @@ +using Microsoft.Extensions.Logging; +using SushiBarContracts.BusinessLogicsContracts; +using SushiBarDataModels.Models; +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 SushiBarView.Shops +{ + public partial class FormSell : Form + { + private readonly ISushiLogic _sushiLogic; + private readonly IShopLogic _shopLogic; + private readonly ILogger _logger; + public FormSell(ILogger logger, IShopLogic shopLogic, ISushiLogic sushiLogic) + { + _logger = logger; + _shopLogic = shopLogic; + _sushiLogic = sushiLogic; + InitializeComponent(); + } + + private void buttonSell_Click(object sender, EventArgs e) + { + if (numericUpDownCountForSelling.Value == 0) + { + MessageBox.Show("Мы не можем продать ноль изделий", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (comboBoxSushis.SelectedValue == null) + { + MessageBox.Show("Выберите изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("Продажа изделий"); + try + { + var operationResult = _shopLogic.SellSushis(_sushiLogic.ReadElement(new() { Id = Convert.ToInt32(comboBoxSushis.SelectedValue) }), + Convert.ToInt32(numericUpDownCountForSelling.Value) + ); + 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 FormSell_Load(object sender, EventArgs e) + { + _logger.LogInformation("Загрузка изделий для продажи"); + try + { + var list = _sushiLogic.ReadList(null); + if (list != null) + { + comboBoxSushis.DisplayMember = "SushiName"; + comboBoxSushis.ValueMember = "Id"; + comboBoxSushis.DataSource = list; + comboBoxSushis.SelectedItem = null; + } + } + 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/SushiBar/Shops/FormSell.resx b/SushiBar/Shops/FormSell.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/SushiBar/Shops/FormSell.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/SushiBar/Shops/FormShop.Designer.cs b/SushiBar/Shops/FormShop.Designer.cs new file mode 100644 index 0000000..066cf3b --- /dev/null +++ b/SushiBar/Shops/FormShop.Designer.cs @@ -0,0 +1,292 @@ +namespace SushiBarView.Shops +{ + 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() + { + buttonCancel = new Button(); + buttonSave = new Button(); + textBoxAddress = new TextBox(); + labelAddress = new Label(); + labelName = new Label(); + dateTimePickerDateOpening = new DateTimePicker(); + groupBoxComponents = new GroupBox(); + buttonRefresh = new Button(); + buttonDelete = new Button(); + buttonUpdate = new Button(); + buttonAdd = new Button(); + dataGridView = new DataGridView(); + ColumnId = new DataGridViewTextBoxColumn(); + ColumnSushiName = new DataGridViewTextBoxColumn(); + ColumnCount = new DataGridViewTextBoxColumn(); + textBoxName = new TextBox(); + labelDateOpening = new Label(); + labelMaxCount = new Label(); + numericUpDownMaxCount = new NumericUpDown(); + groupBoxComponents.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); + ((System.ComponentModel.ISupportInitialize)numericUpDownMaxCount).BeginInit(); + SuspendLayout(); + // + // buttonCancel + // + buttonCancel.Anchor = AnchorStyles.None; + buttonCancel.Location = new Point(710, 431); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(116, 39); + buttonCancel.TabIndex = 11; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += buttonCancel_Click; + // + // buttonSave + // + buttonSave.Anchor = AnchorStyles.None; + buttonSave.Location = new Point(471, 431); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(116, 39); + buttonSave.TabIndex = 10; + buttonSave.Text = "Сохранить"; + buttonSave.UseVisualStyleBackColor = true; + buttonSave.Click += buttonSave_Click; + // + // textBoxAddress + // + textBoxAddress.Anchor = AnchorStyles.None; + textBoxAddress.Location = new Point(124, 46); + textBoxAddress.Name = "textBoxAddress"; + textBoxAddress.Size = new Size(330, 27); + textBoxAddress.TabIndex = 9; + // + // labelAddress + // + labelAddress.Anchor = AnchorStyles.None; + labelAddress.AutoSize = true; + labelAddress.Font = new Font("Candara", 12F); + labelAddress.Location = new Point(24, 46); + labelAddress.Margin = new Padding(4, 0, 4, 0); + labelAddress.Name = "labelAddress"; + labelAddress.Size = new Size(63, 24); + labelAddress.TabIndex = 7; + labelAddress.Text = "Адрес"; + // + // labelName + // + labelName.Anchor = AnchorStyles.None; + labelName.AutoSize = true; + labelName.Font = new Font("Candara", 12F); + labelName.Location = new Point(24, 9); + labelName.Margin = new Padding(4, 0, 4, 0); + labelName.Name = "labelName"; + labelName.Size = new Size(93, 24); + labelName.TabIndex = 6; + labelName.Text = "Название"; + // + // dateTimePickerDateOpening + // + dateTimePickerDateOpening.Location = new Point(471, 46); + dateTimePickerDateOpening.Name = "dateTimePickerDateOpening"; + dateTimePickerDateOpening.Size = new Size(355, 27); + dateTimePickerDateOpening.TabIndex = 12; + // + // groupBoxComponents + // + groupBoxComponents.Controls.Add(buttonRefresh); + groupBoxComponents.Controls.Add(buttonDelete); + groupBoxComponents.Controls.Add(buttonUpdate); + groupBoxComponents.Controls.Add(buttonAdd); + groupBoxComponents.Controls.Add(dataGridView); + groupBoxComponents.Location = new Point(11, 93); + groupBoxComponents.Margin = new Padding(2, 3, 2, 3); + groupBoxComponents.Name = "groupBoxComponents"; + groupBoxComponents.Padding = new Padding(2, 3, 2, 3); + groupBoxComponents.Size = new Size(443, 396); + groupBoxComponents.TabIndex = 18; + groupBoxComponents.TabStop = false; + // + // buttonRefresh + // + buttonRefresh.BackColor = Color.FromArgb(255, 192, 192); + buttonRefresh.Location = new Point(483, 330); + buttonRefresh.Name = "buttonRefresh"; + buttonRefresh.Size = new Size(127, 47); + buttonRefresh.TabIndex = 9; + buttonRefresh.Text = "Обновить"; + buttonRefresh.UseVisualStyleBackColor = false; + // + // buttonDelete + // + buttonDelete.BackColor = Color.FromArgb(255, 192, 192); + buttonDelete.Location = new Point(483, 228); + buttonDelete.Name = "buttonDelete"; + buttonDelete.Size = new Size(127, 47); + buttonDelete.TabIndex = 8; + buttonDelete.Text = "Удалить"; + buttonDelete.UseVisualStyleBackColor = false; + // + // buttonUpdate + // + buttonUpdate.BackColor = Color.FromArgb(255, 192, 192); + buttonUpdate.Location = new Point(483, 125); + buttonUpdate.Name = "buttonUpdate"; + buttonUpdate.Size = new Size(127, 47); + buttonUpdate.TabIndex = 7; + buttonUpdate.Text = "Изменить"; + buttonUpdate.UseVisualStyleBackColor = false; + // + // buttonAdd + // + buttonAdd.BackColor = Color.FromArgb(255, 192, 192); + buttonAdd.Location = new Point(483, 27); + buttonAdd.Name = "buttonAdd"; + buttonAdd.Size = new Size(127, 47); + buttonAdd.TabIndex = 6; + buttonAdd.Text = "Добавить"; + buttonAdd.UseVisualStyleBackColor = false; + // + // dataGridView + // + dataGridView.AllowUserToAddRows = false; + dataGridView.AllowUserToResizeRows = false; + dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + dataGridView.BackgroundColor = Color.FromArgb(255, 192, 192); + dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dataGridView.Columns.AddRange(new DataGridViewColumn[] { ColumnId, ColumnSushiName, ColumnCount }); + dataGridView.Location = new Point(13, 27); + dataGridView.Margin = new Padding(2, 3, 2, 3); + dataGridView.Name = "dataGridView"; + dataGridView.RowHeadersVisible = false; + dataGridView.RowHeadersWidth = 51; + dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; + dataGridView.Size = new Size(419, 350); + dataGridView.TabIndex = 5; + // + // ColumnId + // + ColumnId.HeaderText = "id"; + ColumnId.MinimumWidth = 6; + ColumnId.Name = "ColumnId"; + ColumnId.Visible = false; + // + // ColumnSushiName + // + ColumnSushiName.HeaderText = "Название Суши"; + ColumnSushiName.MinimumWidth = 6; + ColumnSushiName.Name = "ColumnSushiName"; + // + // ColumnCount + // + ColumnCount.HeaderText = "Количество"; + ColumnCount.MinimumWidth = 6; + ColumnCount.Name = "ColumnCount"; + // + // textBoxName + // + textBoxName.Anchor = AnchorStyles.None; + textBoxName.Location = new Point(124, 6); + textBoxName.Name = "textBoxName"; + textBoxName.Size = new Size(330, 27); + textBoxName.TabIndex = 19; + // + // labelDateOpening + // + labelDateOpening.Anchor = AnchorStyles.None; + labelDateOpening.AutoSize = true; + labelDateOpening.Font = new Font("Candara", 12F); + labelDateOpening.Location = new Point(471, 6); + labelDateOpening.Margin = new Padding(4, 0, 4, 0); + labelDateOpening.Name = "labelDateOpening"; + labelDateOpening.Size = new Size(140, 24); + labelDateOpening.TabIndex = 13; + labelDateOpening.Text = "Дата открытия"; + // + // labelMaxCount + // + labelMaxCount.AutoSize = true; + labelMaxCount.Font = new Font("Candara", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); + labelMaxCount.Location = new Point(471, 120); + labelMaxCount.Name = "labelMaxCount"; + labelMaxCount.Size = new Size(261, 24); + labelMaxCount.TabIndex = 20; + labelMaxCount.Text = "Сколько изделий максимум?"; + // + // numericUpDownMaxCount + // + numericUpDownMaxCount.Location = new Point(471, 154); + numericUpDownMaxCount.Name = "numericUpDownMaxCount"; + numericUpDownMaxCount.Size = new Size(355, 27); + numericUpDownMaxCount.TabIndex = 21; + // + // FormShop + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(849, 522); + Controls.Add(numericUpDownMaxCount); + Controls.Add(labelMaxCount); + Controls.Add(textBoxName); + Controls.Add(groupBoxComponents); + Controls.Add(labelDateOpening); + Controls.Add(dateTimePickerDateOpening); + Controls.Add(buttonCancel); + Controls.Add(buttonSave); + Controls.Add(textBoxAddress); + Controls.Add(labelAddress); + Controls.Add(labelName); + Name = "FormShop"; + Text = "Магазин"; + Load += FormShop_Load; + groupBoxComponents.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); + ((System.ComponentModel.ISupportInitialize)numericUpDownMaxCount).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Button buttonCancel; + private Button buttonSave; + private TextBox textBoxAddress; + private Label labelAddress; + private Label labelName; + private DateTimePicker dateTimePickerDateOpening; + private GroupBox groupBoxComponents; + private Button buttonRefresh; + private Button buttonDelete; + private Button buttonUpdate; + private Button buttonAdd; + private DataGridView dataGridView; + private TextBox textBoxName; + private DataGridViewTextBoxColumn ColumnId; + private DataGridViewTextBoxColumn ColumnSushiName; + private DataGridViewTextBoxColumn ColumnCount; + private Label labelDateOpening; + private Label labelMaxCount; + private NumericUpDown numericUpDownMaxCount; + } +} \ No newline at end of file diff --git a/SushiBar/Shops/FormShop.cs b/SushiBar/Shops/FormShop.cs new file mode 100644 index 0000000..0131f54 --- /dev/null +++ b/SushiBar/Shops/FormShop.cs @@ -0,0 +1,128 @@ +using Microsoft.Extensions.Logging; +using SushiBarContracts.BindingModel; +using SushiBarContracts.BusinessLogicsContracts; +using SushiBarContracts.SearchModel; +using SushiBarDataModels.Models; +using System.Windows.Forms; + +namespace SushiBarView.Shops +{ + public partial class FormShop : Form + { + private readonly ILogger _logger; + private readonly IShopLogic _logic; + private int? _id; + public int Id + { + set { _id = value; } + } + + private Dictionary _shopSushis; + public FormShop(ILogger logger, IShopLogic shopLogic) + { + _logger = logger; + _logic = shopLogic; + _shopSushis = new Dictionary(); + InitializeComponent(); + } + + 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; + dateTimePickerDateOpening.Text = view.DateOpening.ToString(); + numericUpDownMaxCount.Value = view.MaxCountSushis; + _shopSushis = view.ShopSushis ?? new Dictionary(); + LoadData(); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки магазина"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void LoadData() + { + _logger.LogInformation("Загрузка изделий магазина"); + try + { + if (_shopSushis != null) + { + dataGridView.Rows.Clear(); + foreach (var elem in _shopSushis) + { + dataGridView.Rows.Add(new object[] + { + elem.Key, + elem.Value.Item1.SushiName, + elem.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($"Сохранение магазина {textBoxName.Text}"); + + try + { + var model = new ShopBindingModel + { + Id = _id ?? 0, + ShopName = textBoxName.Text, + Address = textBoxAddress.Text, + DateOpening = dateTimePickerDateOpening.Value.Date, + MaxCountSushis = Convert.ToInt32(numericUpDownMaxCount.Value), + ShopSushis = _shopSushis + }; + 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/SushiBar/Shops/FormShop.resx b/SushiBar/Shops/FormShop.resx new file mode 100644 index 0000000..4d676b5 --- /dev/null +++ b/SushiBar/Shops/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/SushiBar/Shops/FormShops.Designer.cs b/SushiBar/Shops/FormShops.Designer.cs new file mode 100644 index 0000000..924eb99 --- /dev/null +++ b/SushiBar/Shops/FormShops.Designer.cs @@ -0,0 +1,125 @@ +namespace SushiBarView.Shops +{ + 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(); + buttonRemove = new Button(); + buttonUpdate = new Button(); + buttonAdd = new Button(); + ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); + SuspendLayout(); + // + // dataGridView + // + dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + dataGridView.BackgroundColor = Color.FromArgb(150, 190, 255); + dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dataGridView.Dock = DockStyle.Left; + dataGridView.Location = new Point(0, 0); + dataGridView.MultiSelect = false; + dataGridView.Name = "dataGridView"; + dataGridView.ReadOnly = true; + dataGridView.RowHeadersVisible = false; + dataGridView.RowHeadersWidth = 51; + dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; + dataGridView.Size = new Size(566, 543); + dataGridView.TabIndex = 0; + // + // buttonRefresh + // + buttonRefresh.Font = new Font("Candara", 12F); + buttonRefresh.Location = new Point(626, 453); + buttonRefresh.Name = "buttonRefresh"; + buttonRefresh.Size = new Size(121, 46); + buttonRefresh.TabIndex = 8; + buttonRefresh.Text = "Обновить"; + buttonRefresh.UseVisualStyleBackColor = true; + buttonRefresh.Click += buttonRefresh_Click; + // + // buttonRemove + // + buttonRemove.Font = new Font("Candara", 12F); + buttonRemove.Location = new Point(626, 316); + buttonRemove.Name = "buttonRemove"; + buttonRemove.Size = new Size(121, 46); + buttonRemove.TabIndex = 7; + buttonRemove.Text = "Удалить"; + buttonRemove.UseVisualStyleBackColor = true; + buttonRemove.Click += buttonRemove_Click; + // + // buttonUpdate + // + buttonUpdate.Font = new Font("Candara", 12F); + buttonUpdate.Location = new Point(626, 176); + buttonUpdate.Name = "buttonUpdate"; + buttonUpdate.Size = new Size(121, 46); + buttonUpdate.TabIndex = 6; + buttonUpdate.Text = "Изменить"; + buttonUpdate.UseVisualStyleBackColor = true; + buttonUpdate.Click += buttonUpdate_Click; + // + // buttonAdd + // + buttonAdd.Font = new Font("Candara", 12F); + buttonAdd.Location = new Point(626, 44); + buttonAdd.Name = "buttonAdd"; + buttonAdd.Size = new Size(121, 46); + buttonAdd.TabIndex = 5; + buttonAdd.Text = "Добавить"; + buttonAdd.UseVisualStyleBackColor = true; + buttonAdd.Click += buttonAdd_Click; + // + // FormShops + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = Color.FromArgb(190, 220, 255); + ClientSize = new Size(800, 543); + Controls.Add(buttonRefresh); + Controls.Add(buttonRemove); + Controls.Add(buttonUpdate); + Controls.Add(buttonAdd); + Controls.Add(dataGridView); + Name = "FormShops"; + Text = "Магазины"; + Load += FormShops_LoadData; + ((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); + ResumeLayout(false); + } + + #endregion + + private DataGridView dataGridView; + private Button buttonRefresh; + private Button buttonRemove; + private Button buttonUpdate; + private Button buttonAdd; + } +} \ No newline at end of file diff --git a/SushiBar/Shops/FormShops.cs b/SushiBar/Shops/FormShops.cs new file mode 100644 index 0000000..c8f893e --- /dev/null +++ b/SushiBar/Shops/FormShops.cs @@ -0,0 +1,107 @@ +using Microsoft.Extensions.Logging; +using SushiBar; +using SushiBarContracts.BindingModel; +using SushiBarContracts.BusinessLogicsContracts; +using SushiBarContracts.SearchModel; +using SushiBarDataModels.Models; +using System.Windows.Forms; + +namespace SushiBarView.Shops +{ + public partial class FormShops : Form + { + private readonly ILogger _logger; + private readonly IShopLogic _shopLogic; + + public FormShops(ILogger logger, IShopLogic shopLogic) + { + InitializeComponent(); + _logger = logger; + _shopLogic = shopLogic; + } + + private void FormShops_LoadData(object sender, EventArgs e) + { + LoadData(); + } + + 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 LoadData() + { + try + { + var list = _shopLogic.ReadList(null); + if (list != null) + { + dataGridView.DataSource = list; + dataGridView.Columns["Id"].Visible = false; + dataGridView.Columns["ShopName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + dataGridView.Columns["ShopSushis"].Visible = false; + } + _logger.LogInformation("Загрузка магазинов"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки магазинов"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + 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 buttonRemove_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 (!_shopLogic.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/SushiBar/Shops/FormShops.resx b/SushiBar/Shops/FormShops.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/SushiBar/Shops/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/SushiBarBusinessLogic/OrderLogic.cs b/SushiBarBusinessLogic/OrderLogic.cs index ac24cdd..f146af8 100644 --- a/SushiBarBusinessLogic/OrderLogic.cs +++ b/SushiBarBusinessLogic/OrderLogic.cs @@ -5,6 +5,8 @@ using SushiBarContracts.StoragesContracts; using SushiBarContracts.ViewModels; using Microsoft.Extensions.Logging; using SushiBarDataModels.Enums; +using SushiBarDataModels.Models; +using System.Xml.Linq; namespace SushiBarBusinessLogic.BusinessLogic { @@ -12,11 +14,19 @@ namespace SushiBarBusinessLogic.BusinessLogic { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; + private readonly IShopStorage _shopStorage; + private readonly IShopLogic _shopLogic; + private readonly ISushiStorage _sushiStorage; - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + + public OrderLogic(ILogger logger, IOrderStorage orderStorage, + IShopLogic shopLogic, IShopStorage shopStorage, ISushiStorage sushiStorage) { _logger = logger; _orderStorage = orderStorage; + _shopStorage = shopStorage; + _shopLogic = shopLogic; + _sushiStorage = sushiStorage; } public List? ReadList(OrderSearchModel? model) @@ -53,6 +63,7 @@ namespace SushiBarBusinessLogic.BusinessLogic public bool FinishOrder(OrderBindingModel model) { return ChangeStatus(model, OrderStatus.Готов); + } public bool DeliveryOrder(OrderBindingModel model) @@ -62,24 +73,32 @@ namespace SushiBarBusinessLogic.BusinessLogic private bool ChangeStatus(OrderBindingModel model, OrderStatus orderStatus) { - CheckModel(model, false); var order = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); if (order == null) { _logger.LogWarning("Change status operation failed. Order not found"); - return false; + throw new ArgumentNullException("Не найден заказ... "); } if (order.Status + 1 != orderStatus) { _logger.LogWarning("Change status operation failed. Incorrect new status: {orderStatus}. Current status: {Status}", orderStatus, order.Status); - return false; + throw new ArgumentException("Вы не можете перевести заказ в статус ", nameof(orderStatus)); + } + if(order.Status == OrderStatus.Готов) + { + var sushi = _sushiStorage.GetElement(new SushiSearchModel { Id = order.SushiId }); + if (sushi == null) + { + _logger.LogWarning("Status change error. Sushi not found"); + throw new ArgumentNullException("Суши не нашлись такие... "); + } + if (!CheckSupply(sushi, order.Count)) + { + _logger.LogWarning("Status change error. Shop is overflowed"); + throw new ArgumentOutOfRangeException("Вы не можете выдать заказ, амбары переполнены "); + } } - - model.SushiId = order.SushiId; - model.Count = order.Count; - model.Sum = order.Sum; - model.DateCreate = order.DateCreate; model.Status = orderStatus; if (model.Status == OrderStatus.Готов) @@ -120,5 +139,73 @@ namespace SushiBarBusinessLogic.BusinessLogic _logger.LogInformation("Sushi. SushiId:{SushiId}. Count:{ Count}. Sum:{ Sum}. Id: { Id}", model.SushiId, model.Count, model.Sum, model.Id); } + + public bool CheckSupply(ISushiModel model, int count) + { + if (count <= 0) + { + _logger.LogWarning("Check supply operation error. Planes count < 0"); + return false; + } + + int sumCapacity = _shopStorage.GetFullList().Select(x => x.MaxCountSushis).Sum(); + int sumCount = _shopStorage.GetFullList().Select(x => x.ShopSushis.Select(y => y.Value.Item2).Sum()).Sum(); + int free = sumCapacity - sumCount; + if (free < count) + { + _logger.LogWarning("Check supply error. No place for new sushis"); + return false; + } + + foreach (var shop in _shopStorage.GetFullList()) + { + free = shop.MaxCountSushis; + foreach (var sushi in shop.ShopSushis) + { + free -= sushi.Value.Item2; + } + + if (free == 0) + { + continue; + } + + if (free >= count) + { + if (_shopLogic.AddSushiInShop(new() + { + Id = shop.Id + }, model, count)) + { + count = 0; + } + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + else + { + if (_shopLogic.AddSushiInShop(new() + { + Id = shop.Id + }, model, free)) + { + count -= free; + } + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + if (count <= 0) + { + return true; + } + } + return false; + } } -} +} \ No newline at end of file diff --git a/SushiBarBusinessLogic/ShopLogic.cs b/SushiBarBusinessLogic/ShopLogic.cs new file mode 100644 index 0000000..44202bb --- /dev/null +++ b/SushiBarBusinessLogic/ShopLogic.cs @@ -0,0 +1,173 @@ +using Microsoft.Extensions.Logging; +using SushiBarContracts.BindingModel; +using SushiBarContracts.BusinessLogicsContracts; +using SushiBarContracts.SearchModel; +using SushiBarContracts.StoragesContracts; +using SushiBarContracts.ViewModels; +using SushiBarDataModels; +using SushiBarDataModels.Models; +using System.Numerics; + +namespace SushiBarBusinessLogic +{ + public class ShopLogic : IShopLogic + { + private readonly ILogger _logger; + private readonly IShopStorage _shopStorage; + + + public ShopLogic(ILogger logger, IShopStorage shopStorage) + { + _logger = logger; + _shopStorage = shopStorage; + } + + public List? ReadList(ShopSearchModel? model) + { + _logger.LogInformation("ReadList. Id:{ Id}, ShopName:{ ShopName}", model?.Id, model?.ShopName); + 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 ShopViewModel? ReadElement(ShopSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadList. Id:{ Id}, ShopName:{ ShopName}", model.Id, model.ShopName); + 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 bool Create(ShopBindingModel model) + { + CheckModel(model); + if (_shopStorage.Insert(model) == null) + { + _logger.LogWarning("Вставка в хранилище прервана"); + return false; + } + return true; + } + + public bool Update(ShopBindingModel model) + { + CheckModel(model); + if (_shopStorage.Update(model) == null) + { + _logger.LogWarning("Обновление прервано"); + return false; + } + return true; + } + + public bool Delete(ShopBindingModel model) + { + CheckModel(model); + if (_shopStorage?.Delete(model) == null) + { + _logger.LogWarning("Удаление прервано"); + return false; + } + return true; + } + + public bool AddSushiInShop(ShopSearchModel model, ISushiModel sushi, int count) + { + if (model == null) + throw new ArgumentNullException("Не найден такой магазин... \n", nameof(model)); + if (count <= 0) + throw new ArgumentException("Количество суши должно быть больше нуля, ало \n", nameof(count)); + _logger.LogInformation("Добавлены суши в магазин: {ShopName}.Id:{ Id}", model.ShopName, model.Id); + + var element = _shopStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("Не добавлено, магазин не найден с таким названием"); + return false; + } + var countSushis = element.ShopSushis.Select(x => x.Value.Item2).Sum(); + if (element.MaxCountSushis - countSushis < count) + { + _logger.LogWarning("В магазине не хватает места"); + throw new ArgumentOutOfRangeException("Не зватает места в магазине, увы... кушать меньше надо ", nameof(countSushis)); + } + if (element.ShopSushis.TryGetValue(sushi.Id, out var samesushi)) + { + element.ShopSushis[sushi.Id] = (sushi, samesushi.Item2 + count); + _logger.LogInformation("Same sushi found by supply. Added {0} of {1} in {2} shop", count, sushi.SushiName, element.ShopName); + } + else + { + element.ShopSushis[sushi.Id] = (sushi, count); + _logger.LogInformation("New sushi added by supply. Added {0} of {1} in {2} shop", count, sushi.SushiName, element.ShopName); + } + + _shopStorage.Update(new() + { + Id = element.Id, + ShopName = element.ShopName, + Address = element.Address, + DateOpening = element.DateOpening, + ShopSushis = element.ShopSushis, + MaxCountSushis = element.MaxCountSushis, + }); + + return true; + } + + public bool SellSushis(ISushiModel sushi, int count) + { + if (sushi == null) + { + throw new ArgumentNullException("Не найдены такие суши, их нет в магазинах... \n", nameof(sushi)); + } + if (count <= 0) + { + throw new ArgumentNullException("Количество суши должно быть больше нуля! алло!\n", nameof(count)); + } + if (_shopStorage.SellSushis(sushi, count)) + { + _logger.LogInformation("Selling sucsess"); + return true; + } + _logger.LogInformation("Selling failed"); + return false; + } + + + private void CheckModel(ShopBindingModel model, bool withParams = true) + { + if (model == null) + throw new ArgumentNullException($"{nameof(model)} является null"); + if (!withParams) return; + if (string.IsNullOrEmpty(model.ShopName)) + { + throw new ArgumentNullException("Нет такого магазина ", nameof(model.ShopName)); + } + _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 && element.ShopName == model.ShopName) + { + throw new InvalidOperationException("Такой магазин с таким названием уже есть"); + } + } + } +} diff --git a/SushiBarContracts/BindingModel/ShopBindingModel.cs b/SushiBarContracts/BindingModel/ShopBindingModel.cs new file mode 100644 index 0000000..cdbdc3b --- /dev/null +++ b/SushiBarContracts/BindingModel/ShopBindingModel.cs @@ -0,0 +1,15 @@ +using SushiBarDataModels; +using SushiBarDataModels.Models; + +namespace SushiBarContracts.BindingModel +{ + public class ShopBindingModel : IShopModel + { + public int Id { get; set; } + public int MaxCountSushis { get; set; } + public string ShopName { get; set; } + public string Address { get; set; } + public DateTime DateOpening { get; set; } = DateTime.Now; + public Dictionary ShopSushis { get; set; } = new(); + } +} diff --git a/SushiBarContracts/BusinessLogicsContracts/IShopLogic.cs b/SushiBarContracts/BusinessLogicsContracts/IShopLogic.cs new file mode 100644 index 0000000..5b600b2 --- /dev/null +++ b/SushiBarContracts/BusinessLogicsContracts/IShopLogic.cs @@ -0,0 +1,18 @@ +using SushiBarContracts.BindingModel; +using SushiBarContracts.SearchModel; +using SushiBarContracts.ViewModels; +using SushiBarDataModels.Models; + +namespace SushiBarContracts.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 AddSushiInShop(ShopSearchModel model, ISushiModel sushi, int count); + bool SellSushis(ISushiModel sushi, int count); + } +} diff --git a/SushiBarContracts/SearchModel/ShopSearchModel.cs b/SushiBarContracts/SearchModel/ShopSearchModel.cs new file mode 100644 index 0000000..e725658 --- /dev/null +++ b/SushiBarContracts/SearchModel/ShopSearchModel.cs @@ -0,0 +1,8 @@ +namespace SushiBarContracts.SearchModel +{ + public class ShopSearchModel + { + public int? Id { get; set; } + public string? ShopName { get; set; } + } +} diff --git a/SushiBarContracts/StoragesContracts/IShopStorage.cs b/SushiBarContracts/StoragesContracts/IShopStorage.cs new file mode 100644 index 0000000..fb4fd71 --- /dev/null +++ b/SushiBarContracts/StoragesContracts/IShopStorage.cs @@ -0,0 +1,19 @@ +using SushiBarContracts.BindingModel; +using SushiBarContracts.SearchModel; +using SushiBarContracts.ViewModels; +using SushiBarDataModels.Models; + +namespace SushiBarContracts.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 SellSushis(ISushiModel model, int count); + bool CheckCountSushi(ISushiModel model, int count); + } +} diff --git a/SushiBarContracts/ViewModels/ShopViewModel.cs b/SushiBarContracts/ViewModels/ShopViewModel.cs new file mode 100644 index 0000000..a19a7c8 --- /dev/null +++ b/SushiBarContracts/ViewModels/ShopViewModel.cs @@ -0,0 +1,24 @@ +using SushiBarDataModels; +using SushiBarDataModels.Models; +using System.ComponentModel; + +namespace SushiBarContracts.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 int MaxCountSushis { get; set; } + + [DisplayName("Дата открытия")] + public DateTime DateOpening { get; set; } = DateTime.Now; + public Dictionary ShopSushis { get; set; } = new(); + } +} diff --git a/SushiBarDataModels/IShopModel.cs b/SushiBarDataModels/IShopModel.cs new file mode 100644 index 0000000..d998d31 --- /dev/null +++ b/SushiBarDataModels/IShopModel.cs @@ -0,0 +1,13 @@ +using SushiBarDataModels.Models; + +namespace SushiBarDataModels +{ + public interface IShopModel : IId + { + int MaxCountSushis { get; } + string ShopName { get; } + string Address { get; } + DateTime DateOpening { get; } + Dictionary ShopSushis{ get; } + } +} diff --git a/SushiBarDatabaseImplement/Implements/ShopStorage.cs b/SushiBarDatabaseImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..6808051 --- /dev/null +++ b/SushiBarDatabaseImplement/Implements/ShopStorage.cs @@ -0,0 +1,260 @@ +using Microsoft.EntityFrameworkCore; +using SushiBarContracts.BindingModel; +using SushiBarContracts.SearchModel; +using SushiBarContracts.StoragesContracts; +using SushiBarContracts.ViewModels; +using SushiBarDatabaseImplement.Models; +using SushiBarDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SushiBarDatabaseImplement.Implements +{ + public class ShopStorage : IShopStorage + { + + public List GetFullList() + { + using var context = new SushiBarDatabase(); + return context.Shops + .Include(x => x.Sushis) + .ThenInclude(x => x.Sushi) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + /// + /// Получение фильтрованного списка + /// + /// + /// + public List GetFilteredList(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName)) + { + return new(); + } + + using var context = new SushiBarDatabase(); + return context.Shops + .Include(x => x.Sushis) + .ThenInclude(x => x.Sushi) + .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 null; + } + + using var context = new SushiBarDatabase(); + return context.Shops + .Include(x => x.Sushis) + .ThenInclude(x => x.Sushi) + .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 SushiBarDatabase(); + 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 SushiBarDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + var shop = context.Shops.FirstOrDefault(rec => rec.Id == model.Id); + if (shop == null) + { + return null; + } + + shop.Update(model); + context.SaveChanges(); + shop.UpdateSushis(context, model); + transaction.Commit(); + return shop.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + + /// + /// Удаление элемента + /// + /// + /// + public ShopViewModel? Delete(ShopBindingModel model) + { + using var context = new SushiBarDatabase(); + var element = context.Shops + .Include(x => x.Sushis) + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Shops.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + /// + /// Продажа изделий + /// + /// + /// + /// + public bool SellSushis(ISushiModel model, int count) + { + using var context = new SushiBarDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + var shops = context.Shops + .Include(x => x.Sushis) + .ThenInclude(x => x.Sushi) + .ToList() + .Where(x => x.ShopSushis.ContainsKey(model.Id)); + + foreach (var shop in shops) + { + int countInCurrentShop = shop.ShopSushis[model.Id].Item2; + if (countInCurrentShop <= count) + { + var elem = context.ShopSushis + .Where(x => x.SushiId == model.Id) + .FirstOrDefault(x => x.ShopId == shop.Id); + context.ShopSushis.Remove(elem); + shop.ShopSushis.Remove(model.Id); + count -= countInCurrentShop; + } + else + { + shop.ShopSushis[model.Id] = (shop.ShopSushis[model.Id].Item1, countInCurrentShop - count); + count = 0; + shop.UpdateSushis(context, new ShopBindingModel + { + Id = shop.Id, + ShopName = shop.ShopName, + Address = shop.Address, + DateOpening = shop.DateOpening, + ShopSushis = shop.ShopSushis, + MaxCountSushis = shop.MaxCountSushis + }); + } + if (count <= 0) + { + context.SaveChanges(); + transaction.Commit(); + return true; + } + } + transaction.Rollback(); + return false; + } + catch + { + transaction.Rollback(); + throw; + } + } + + /// + /// Проверка наличия в нужном количестве + /// + /// + /// + /// + /// + public bool CheckCountSushi(ISushiModel model, int count) + { + throw new NotImplementedException(); + } + /*public bool CheckCountSushi(ISushiModel model, int count) + { + int store = _source.Shops.Select(x => x.ShopSushis.Select(y => + (y.Value.Item1.Id == model.Id ? y.Value.Item2 : 0)).Sum()).Sum(); + return store >= count; + } + + public bool SellSushis(ISushiModel model, int count) + { + var sushi = _source.Sushis.FirstOrDefault(x => x.Id == model.Id); + if (sushi == null || !CheckCountSushi(model, count)) + { + throw new ArgumentNullException("Такого количества суш нет, продать столько низя "); + } + + foreach (var shop in _source.Shops) + { + var sushis = shop.ShopSushis; + foreach (var elem in sushis.Where(x => x.Value.Item1.Id == sushi.Id)) + { + var selling = Math.Min(elem.Value.Item2, count); + sushis[elem.Value.Item1.Id] = (elem.Value.Item1, elem.Value.Item2 - selling); + count -= selling; + + if (count <= 0) + { + break; + } + } + + shop.Update(new ShopBindingModel + { + Id = model.Id, + ShopName = shop.ShopName, + Address = shop.Address, + DateOpening = shop.DateOpening, + ShopSushis = sushis, + MaxCountSushis = shop.MaxCountSushis + }); + } + + _source.SaveShops(); + return true; + }*/ + } +} diff --git a/SushiBarDatabaseImplement/Migrations/20240310073215_InitCreate.Designer.cs b/SushiBarDatabaseImplement/Migrations/20240421182209_InitCreate.Designer.cs similarity index 68% rename from SushiBarDatabaseImplement/Migrations/20240310073215_InitCreate.Designer.cs rename to SushiBarDatabaseImplement/Migrations/20240421182209_InitCreate.Designer.cs index 761e375..08c09f4 100644 --- a/SushiBarDatabaseImplement/Migrations/20240310073215_InitCreate.Designer.cs +++ b/SushiBarDatabaseImplement/Migrations/20240421182209_InitCreate.Designer.cs @@ -12,7 +12,7 @@ using SushiBarDatabaseImplement; namespace SushiBarDatabaseImplement.Migrations { [DbContext(typeof(SushiBarDatabase))] - [Migration("20240310073215_InitCreate")] + [Migration("20240421182209_InitCreate")] partial class InitCreate { /// @@ -78,6 +78,59 @@ namespace SushiBarDatabaseImplement.Migrations b.ToTable("Orders"); }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Shop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DateOpening") + .HasColumnType("datetime2"); + + b.Property("MaxCountSushis") + .HasColumnType("int"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("SushiBarDatabaseImplement.Models.ShopSushi", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.Property("SushiId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ShopId"); + + b.HasIndex("SushiId"); + + b.ToTable("ShopSushis"); + }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Sushi", b => { b.Property("Id") @@ -133,6 +186,25 @@ namespace SushiBarDatabaseImplement.Migrations .IsRequired(); }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.ShopSushi", b => + { + b.HasOne("SushiBarDatabaseImplement.Models.Shop", "Shop") + .WithMany("Sushis") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi") + .WithMany() + .HasForeignKey("SushiId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Shop"); + + b.Navigation("Sushi"); + }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.SushiComponent", b => { b.HasOne("SushiBarDatabaseImplement.Models.Component", "Component") @@ -157,6 +229,11 @@ namespace SushiBarDatabaseImplement.Migrations b.Navigation("SushiComponents"); }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Shop", b => + { + b.Navigation("Sushis"); + }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Sushi", b => { b.Navigation("Components"); diff --git a/SushiBarDatabaseImplement/Migrations/20240310073215_InitCreate.cs b/SushiBarDatabaseImplement/Migrations/20240421182209_InitCreate.cs similarity index 66% rename from SushiBarDatabaseImplement/Migrations/20240310073215_InitCreate.cs rename to SushiBarDatabaseImplement/Migrations/20240421182209_InitCreate.cs index 6c95139..278fc76 100644 --- a/SushiBarDatabaseImplement/Migrations/20240310073215_InitCreate.cs +++ b/SushiBarDatabaseImplement/Migrations/20240421182209_InitCreate.cs @@ -25,6 +25,22 @@ namespace SushiBarDatabaseImplement.Migrations table.PrimaryKey("PK_Components", x => x.Id); }); + 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), + DateOpening = table.Column(type: "datetime2", nullable: false), + MaxCountSushis = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Shops", x => x.Id); + }); + migrationBuilder.CreateTable( name: "Sushis", columns: table => new @@ -63,6 +79,33 @@ namespace SushiBarDatabaseImplement.Migrations onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "ShopSushis", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + SushiId = 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_ShopSushis", x => x.Id); + table.ForeignKey( + name: "FK_ShopSushis_Shops_ShopId", + column: x => x.ShopId, + principalTable: "Shops", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ShopSushis_Sushis_SushiId", + column: x => x.SushiId, + principalTable: "Sushis", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateTable( name: "SushiComponents", columns: table => new @@ -95,6 +138,16 @@ namespace SushiBarDatabaseImplement.Migrations table: "Orders", column: "SushiId"); + migrationBuilder.CreateIndex( + name: "IX_ShopSushis_ShopId", + table: "ShopSushis", + column: "ShopId"); + + migrationBuilder.CreateIndex( + name: "IX_ShopSushis_SushiId", + table: "ShopSushis", + column: "SushiId"); + migrationBuilder.CreateIndex( name: "IX_SushiComponents_ComponentId", table: "SushiComponents", @@ -112,9 +165,15 @@ namespace SushiBarDatabaseImplement.Migrations migrationBuilder.DropTable( name: "Orders"); + migrationBuilder.DropTable( + name: "ShopSushis"); + migrationBuilder.DropTable( name: "SushiComponents"); + migrationBuilder.DropTable( + name: "Shops"); + migrationBuilder.DropTable( name: "Components"); diff --git a/SushiBarDatabaseImplement/Migrations/SushiBarDatabaseModelSnapshot.cs b/SushiBarDatabaseImplement/Migrations/SushiBarDatabaseModelSnapshot.cs index e8ebc24..c0b8d48 100644 --- a/SushiBarDatabaseImplement/Migrations/SushiBarDatabaseModelSnapshot.cs +++ b/SushiBarDatabaseImplement/Migrations/SushiBarDatabaseModelSnapshot.cs @@ -75,6 +75,59 @@ namespace SushiBarDatabaseImplement.Migrations b.ToTable("Orders"); }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Shop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DateOpening") + .HasColumnType("datetime2"); + + b.Property("MaxCountSushis") + .HasColumnType("int"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("SushiBarDatabaseImplement.Models.ShopSushi", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.Property("SushiId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ShopId"); + + b.HasIndex("SushiId"); + + b.ToTable("ShopSushis"); + }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Sushi", b => { b.Property("Id") @@ -130,6 +183,25 @@ namespace SushiBarDatabaseImplement.Migrations .IsRequired(); }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.ShopSushi", b => + { + b.HasOne("SushiBarDatabaseImplement.Models.Shop", "Shop") + .WithMany("Sushis") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi") + .WithMany() + .HasForeignKey("SushiId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Shop"); + + b.Navigation("Sushi"); + }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.SushiComponent", b => { b.HasOne("SushiBarDatabaseImplement.Models.Component", "Component") @@ -154,6 +226,11 @@ namespace SushiBarDatabaseImplement.Migrations b.Navigation("SushiComponents"); }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Shop", b => + { + b.Navigation("Sushis"); + }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Sushi", b => { b.Navigation("Components"); diff --git a/SushiBarDatabaseImplement/Models/Shop.cs b/SushiBarDatabaseImplement/Models/Shop.cs new file mode 100644 index 0000000..7ab92a5 --- /dev/null +++ b/SushiBarDatabaseImplement/Models/Shop.cs @@ -0,0 +1,113 @@ +using SushiBarContracts.BindingModel; +using SushiBarContracts.ViewModels; +using SushiBarDataModels; +using SushiBarDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace SushiBarDatabaseImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + + [Required] + public string ShopName { get; private set; } + + [Required] + public string Address { get; private set; } + + [Required] + public DateTime DateOpening { get; private set; } + + [Required] + public int MaxCountSushis { get; private set; } + + [ForeignKey("ShopId")] + public List Sushis { get; private set; } = new(); + + private Dictionary? _shopSushis = null; + + [NotMapped] + public Dictionary ShopSushis + { + get + { + if (_shopSushis == null) + { + _shopSushis = Sushis.ToDictionary(recPC => recPC.SushiId, recPC => (recPC.Sushi as ISushiModel, recPC.Count)); + } + return _shopSushis; + } + } + + public static Shop Create(SushiBarDatabase context, ShopBindingModel model) + { + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + MaxCountSushis = model.MaxCountSushis, + DateOpening = model.DateOpening, + Sushis = model.ShopSushis.Select(x => new ShopSushi + { + Sushi = context.Sushis.First(y => y.Id == x.Key), Count = x.Value.Item2 + }).ToList() + }; + } + public void Update(ShopBindingModel model) + { + ShopName = model.ShopName; + Address = model.Address; + DateOpening = model.DateOpening; + MaxCountSushis = model.MaxCountSushis; + } + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpening = DateOpening, + MaxCountSushis = MaxCountSushis, + ShopSushis = ShopSushis + }; + public void UpdateSushis(SushiBarDatabase context, ShopBindingModel model) + { + var ShopSushis = context.ShopSushis.Where(rec => rec.ShopId == model.Id).ToList(); + if (ShopSushis != null && ShopSushis.Count > 0) + { + // удалили те, которых нет в модели + context.ShopSushis.RemoveRange(ShopSushis.Where(rec => !model.ShopSushis.ContainsKey(rec.SushiId))); + context.SaveChanges(); + ShopSushis = context.ShopSushis.Where(rec => rec.ShopId == model.Id).ToList(); + // обновили количество у существующих записей + foreach (var updateSushi in ShopSushis) + { + updateSushi.Count = model.ShopSushis[updateSushi.SushiId].Item2; + model.ShopSushis.Remove(updateSushi.SushiId); + } + context.SaveChanges(); + } + var shop = context.Shops.First(x => x.Id == Id); + foreach (var elem in model.ShopSushis) + { + context.ShopSushis.Add(new ShopSushi + { + Shop = shop, + Sushi = context.Sushis.First(x => x.Id == elem.Key), + Count = elem.Value.Item2 + }); + context.SaveChanges(); + } + _shopSushis = null; + } + } +} \ No newline at end of file diff --git a/SushiBarDatabaseImplement/Models/ShopSushi.cs b/SushiBarDatabaseImplement/Models/ShopSushi.cs new file mode 100644 index 0000000..5317784 --- /dev/null +++ b/SushiBarDatabaseImplement/Models/ShopSushi.cs @@ -0,0 +1,27 @@ +using SushiBarListImplements.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Runtime.ConstrainedExecution; +using System.Text; +using System.Threading.Tasks; + +namespace SushiBarDatabaseImplement.Models +{ + public class ShopSushi + { + public int Id { get; set; } + + [Required] + public int SushiId { get; set; } + + [Required] + public int ShopId { get; set; } + + [Required] + public int Count { get; set; } + public virtual Shop Shop { get; set; } = new(); + public virtual Sushi Sushi { get; set; } = new(); + } +} diff --git a/SushiBarDatabaseImplement/Models/Sushi.cs b/SushiBarDatabaseImplement/Models/Sushi.cs index 9e3a64e..25de728 100644 --- a/SushiBarDatabaseImplement/Models/Sushi.cs +++ b/SushiBarDatabaseImplement/Models/Sushi.cs @@ -10,11 +10,15 @@ namespace SushiBarDatabaseImplement.Models public class Sushi : ISushiModel { public int Id { get; set; } + [Required] public string SushiName { get; set; } = string.Empty; + [Required] public double Price { get; set; } + private Dictionary? _sushiComponents = null; + [NotMapped] public Dictionary SushiComponents { diff --git a/SushiBarDatabaseImplement/SushiBarDatabase.cs b/SushiBarDatabaseImplement/SushiBarDatabase.cs index 013642e..a410774 100644 --- a/SushiBarDatabaseImplement/SushiBarDatabase.cs +++ b/SushiBarDatabaseImplement/SushiBarDatabase.cs @@ -24,5 +24,7 @@ namespace SushiBarDatabaseImplement public virtual DbSet Sushis { set; get; } public virtual DbSet SushiComponents { set; get; } public virtual DbSet Orders { set; get; } + public virtual DbSet Shops { set; get; } + public virtual DbSet ShopSushis { set; get; } } } diff --git a/SushiBarFileImplement/DataFileSingleton.cs b/SushiBarFileImplement/DataFileSingleton.cs index 7f5603c..6366fcd 100644 --- a/SushiBarFileImplement/DataFileSingleton.cs +++ b/SushiBarFileImplement/DataFileSingleton.cs @@ -13,9 +13,12 @@ namespace SushiBarFileImplement private readonly string SushiFileName = "Sushi.xml"; + private readonly string ShopFileName = "Shop.xml"; + public List Components { get; private set; } public List Orders { get; private set; } public List Sushis { get; private set; } + public List Shops { get; private set; } public static DataFileSingleton GetInstance() { @@ -29,12 +32,14 @@ namespace SushiBarFileImplement public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); public void SaveSushis() => SaveData(Sushis, SushiFileName, "Sushis", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", x => x.GetXElement); private DataFileSingleton() { Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!; Sushis = LoadData(SushiFileName, "Sushi", x => Sushi.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/SushiBarFileImplement/Implements/ShopStorage.cs b/SushiBarFileImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..c2bd26d --- /dev/null +++ b/SushiBarFileImplement/Implements/ShopStorage.cs @@ -0,0 +1,125 @@ +using SushiBarContracts.BindingModel; +using SushiBarContracts.SearchModel; +using SushiBarContracts.StoragesContracts; +using SushiBarContracts.ViewModels; +using SushiBarDataModels.Models; +using SushiBarFileImplement.Models; + +namespace SushiBarFileImplement.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 component = _source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (component == null) + { + return null; + } + component.Update(model); + _source.SaveShops(); + return component.GetViewModel; + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + var element = _source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + _source.Shops.Remove(element); + _source.SaveShops(); + return element.GetViewModel; + } + return null; + } + + public bool CheckCountSushi(ISushiModel model, int count) + { + int store = _source.Shops.Select(x => x.ShopSushis.Select(y => + (y.Value.Item1.Id == model.Id ? y.Value.Item2 : 0)).Sum()).Sum(); + return store >= count; + } + + public bool SellSushis(ISushiModel model, int count) + { + var sushi = _source.Sushis.FirstOrDefault(x => x.Id == model.Id); + if (sushi == null || !CheckCountSushi(model, count)) + { + throw new ArgumentNullException("Такого количества суш нет, продать столько низя "); + } + + foreach (var shop in _source.Shops) + { + var sushis = shop.ShopSushis; + foreach (var elem in sushis.Where(x => x.Value.Item1.Id == sushi.Id)) + { + var selling = Math.Min(elem.Value.Item2, count); + sushis[elem.Value.Item1.Id] = (elem.Value.Item1, elem.Value.Item2 - selling); + count -= selling; + + if (count <= 0) + { + break; + } + } + + shop.Update(new ShopBindingModel + { + Id = model.Id, + ShopName = shop.ShopName, + Address = shop.Address, + DateOpening = shop.DateOpening, + ShopSushis = sushis, + MaxCountSushis = shop.MaxCountSushis + }); + } + + _source.SaveShops(); + return true; + } + } +} diff --git a/SushiBarFileImplement/Implements/SushiStorage.cs b/SushiBarFileImplement/Implements/SushiStorage.cs index 2845db6..b731300 100644 --- a/SushiBarFileImplement/Implements/SushiStorage.cs +++ b/SushiBarFileImplement/Implements/SushiStorage.cs @@ -31,7 +31,7 @@ namespace SushiBarFileImplement.Implements public SushiViewModel? GetElement(SushiSearchModel model) { - if (string.IsNullOrEmpty(model.SushiName) && !model.Id.HasValue) + if (!model.Id.HasValue) { return null; } diff --git a/SushiBarFileImplement/Models/Shop.cs b/SushiBarFileImplement/Models/Shop.cs new file mode 100644 index 0000000..bf5de90 --- /dev/null +++ b/SushiBarFileImplement/Models/Shop.cs @@ -0,0 +1,103 @@ +using SushiBarContracts.BindingModel; +using SushiBarContracts.ViewModels; +using SushiBarDataModels; +using SushiBarDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace SushiBarFileImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + public string ShopName { get; private set; } + public string Address { get; private set; } + public DateTime DateOpening { get; private set; } + public int MaxCountSushis { get; private set; } + public Dictionary Sushis { get; private set; } = new(); + + private Dictionary? _shopSushis = null; + public Dictionary ShopSushis + { + get + { + if (_shopSushis == null) + { + var source = DataFileSingleton.GetInstance(); + _shopSushis = Sushis.ToDictionary(x => x.Key, y => ((source.Sushis.FirstOrDefault(z => z.Id == y.Key) as ISushiModel)!, y.Value)); + } + return _shopSushis; + } + } + public static Shop? Create(ShopBindingModel model) + { + if (model == null) + { + return null; + } + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOpening = model.DateOpening, + MaxCountSushis = model.MaxCountSushis, + Sushis = model.ShopSushis.ToDictionary(x => x.Key, x => x.Value.Item2) + }; + } + public static Shop? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Shop() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ShopName = element.Element("ShopName")!.Value, + Address = element.Element("Address")!.Value, + MaxCountSushis = Convert.ToInt32(element.Element("MaxCountSushis")!.Value), + DateOpening = Convert.ToDateTime(element.Element("DateOpening")!.Value), + Sushis = element.Element("ShopSushis")!.Elements("ShopSushis").ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value)) + }; + + } + public void Update(ShopBindingModel? model) + { + if (model == null) + { + return; + } + ShopName = model.ShopName; + Address = model.Address; + DateOpening = model.DateOpening; + MaxCountSushis = model.MaxCountSushis; + if (model.ShopSushis.Count > 0) + { + Sushis = model.ShopSushis.ToDictionary(x => x.Key, x => x.Value.Item2); + _shopSushis = null; + } + } + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpening = DateOpening, + MaxCountSushis = MaxCountSushis, + ShopSushis = ShopSushis + }; + + public XElement GetXElement => new XElement("Shop", + new XAttribute("Id", Id), + new XElement("ShopName", ShopName), + new XElement("Address", Address), + new XElement("DateOpening", DateOpening), + new XElement("MaxCountSushis", MaxCountSushis), + new XElement("ShopSushis", Sushis.Select(x => new XElement("ShopSushis", new XElement("Key", x.Key), new XElement("Value", x.Value))).ToArray())); + } +} diff --git a/SushiBarListImplements/DataListSingleton.cs b/SushiBarListImplements/DataListSingleton.cs index 309dfcd..58df67f 100644 --- a/SushiBarListImplements/DataListSingleton.cs +++ b/SushiBarListImplements/DataListSingleton.cs @@ -8,11 +8,14 @@ namespace SushiBarListImplement public List Components { get; set; } public List Orders { get; set; } public List Sushis { get; set; } + public List Shops { get; set; } + private DataListSingleton() { Components = new List(); Orders = new List(); Sushis = new List(); + Shops = new List(); } public static DataListSingleton GetInstance() { diff --git a/SushiBarListImplements/Implements/ShopStorage.cs b/SushiBarListImplements/Implements/ShopStorage.cs new file mode 100644 index 0000000..851b3f4 --- /dev/null +++ b/SushiBarListImplements/Implements/ShopStorage.cs @@ -0,0 +1,121 @@ +using SushiBarContracts.BindingModel; +using SushiBarContracts.SearchModel; +using SushiBarContracts.StoragesContracts; +using SushiBarContracts.ViewModels; +using SushiBarDataModels.Models; +using SushiBarListImplement; +using SushiBarListImplements.Models; + +namespace SushiBarListImplements.Implements +{ + public class ShopStorage : IShopStorage + { + private 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 SellSushis(ISushiModel model, int count) + { + return true; + } + + public bool CheckCountSushi(ISushiModel model, int count) + { + return true; + } + } +} diff --git a/SushiBarListImplements/Models/Shop.cs b/SushiBarListImplements/Models/Shop.cs new file mode 100644 index 0000000..e749a20 --- /dev/null +++ b/SushiBarListImplements/Models/Shop.cs @@ -0,0 +1,61 @@ +using SushiBarContracts.BindingModel; +using SushiBarContracts.ViewModels; +using SushiBarDataModels; +using SushiBarDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace SushiBarListImplements.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + public int MaxCountSushis { get; private set; } + public string ShopName { get; private set; } + public string Address { get; private set; } + public DateTime DateOpening { get; private set; } = DateTime.Now; + public Dictionary ShopSushis + { + get; + private set; + } = new Dictionary(); + + public static Shop? Create(ShopBindingModel? model) + { + if(model == null) return null; + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOpening = model.DateOpening, + ShopSushis = model.ShopSushis, + MaxCountSushis = model.MaxCountSushis + }; + } + + public void Update(ShopBindingModel? model) + { + if (model == null) return; + ShopName = model.ShopName; + Address = model.Address; + DateOpening = model.DateOpening; + ShopSushis = model.ShopSushis; + MaxCountSushis = model.MaxCountSushis; + } + + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpening = DateOpening, + ShopSushis = ShopSushis, + MaxCountSushis = MaxCountSushis + }; + } +}