diff --git a/FoodOrders/FoodOrders/FormSellCars.Designer.cs b/FoodOrders/FoodOrders/FormSellCars.Designer.cs new file mode 100644 index 0000000..c06d374 --- /dev/null +++ b/FoodOrders/FoodOrders/FormSellCars.Designer.cs @@ -0,0 +1,120 @@ +namespace FoodOrdersView +{ + partial class FormSellDishes + { + /// + /// 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(); + buttonSell = new Button(); + labelDish = new Label(); + labelCount = new Label(); + comboBoxDish = new ComboBox(); + textBoxCount = new TextBox(); + SuspendLayout(); + // + // buttonCancel + // + buttonCancel.Location = new Point(383, 167); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(112, 34); + buttonCancel.TabIndex = 0; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += ButtonCancel_Click; + // + // buttonSell + // + buttonSell.Location = new Point(265, 167); + buttonSell.Name = "buttonSell"; + buttonSell.Size = new Size(112, 34); + buttonSell.TabIndex = 1; + buttonSell.Text = "Продать"; + buttonSell.UseVisualStyleBackColor = true; + buttonSell.Click += ButtonSell_Click; + // + // labelDish + // + labelDish.AutoSize = true; + labelDish.Location = new Point(12, 37); + labelDish.Name = "labelDish"; + labelDish.Size = new Size(118, 25); + labelDish.TabIndex = 2; + labelDish.Text = "Блюдо:"; + // + // labelCount + // + labelCount.AutoSize = true; + labelCount.Location = new Point(12, 81); + labelCount.Name = "labelCount"; + labelCount.Size = new Size(111, 25); + labelCount.TabIndex = 3; + labelCount.Text = "Количество:"; + // + // comboBoxDish + // + comboBoxDish.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxDish.FormattingEnabled = true; + comboBoxDish.Location = new Point(129, 37); + comboBoxDish.Name = "comboBoxDish"; + comboBoxDish.Size = new Size(318, 33); + comboBoxDish.TabIndex = 4; + // + // textBoxCount + // + textBoxCount.Location = new Point(129, 81); + textBoxCount.Name = "textBoxCount"; + textBoxCount.Size = new Size(318, 31); + textBoxCount.TabIndex = 5; + // + // FormSellDishes + // + AutoScaleDimensions = new SizeF(10F, 25F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(507, 213); + Controls.Add(textBoxCount); + Controls.Add(comboBoxDish); + Controls.Add(labelCount); + Controls.Add(labelDish); + Controls.Add(buttonSell); + Controls.Add(buttonCancel); + Name = "FormSellDishes"; + Text = "Продажа блюд"; + Load += FormSellDishes_Load; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Button buttonCancel; + private Button buttonSell; + private Label labelDish; + private Label labelCount; + private ComboBox comboBoxDish; + private TextBox textBoxCount; + } +} \ No newline at end of file diff --git a/FoodOrders/FoodOrders/FormSellCars.cs b/FoodOrders/FoodOrders/FormSellCars.cs new file mode 100644 index 0000000..131171b --- /dev/null +++ b/FoodOrders/FoodOrders/FormSellCars.cs @@ -0,0 +1,92 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.BusinessLogicsContracts; +using FoodOrdersContracts.SearchModels; +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 FoodOrdersView +{ + public partial class FormSellDishes : Form + { + private readonly ILogger _logger; + private readonly IDishLogic _logicC; + private readonly IShopLogic _logicS; + public FormSellDishes(ILogger logger, IDishLogic logicC, IShopLogic logicS) + { + InitializeComponent(); + _logger = logger; + _logicC = logicC; + _logicS = logicS; + } + + private void FormSellDishes_Load(object sender, EventArgs e) + { + _logger.LogInformation("Загрузка блюд под продажу"); + try + { + var list = _logicC.ReadList(null); + if (list != null) + { + comboBoxDish.DisplayMember = "DishName"; + comboBoxDish.ValueMember = "Id"; + comboBoxDish.DataSource = list; + comboBoxDish.SelectedItem = null; + } + + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки списка блюд"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + private void ButtonSell_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(textBoxCount.Text)) + { + MessageBox.Show("Заполните поле 'Количество'", "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (comboBoxDish.SelectedValue == null) + { + MessageBox.Show("Выберите блюдо", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("Продажа блюд"); + try + { + var operationResult = _logicS.SellDishes(_logicC.ReadElement + (new DishSearchModel { DishName = comboBoxDish.Text})!, + 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/FoodOrders/FoodOrders/FormSellCars.resx b/FoodOrders/FoodOrders/FormSellCars.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/FoodOrders/FoodOrders/FormSellCars.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/FoodOrders/FoodOrders/FormShop.Designer.cs b/FoodOrders/FoodOrders/FormShop.Designer.cs index 0c9e0f4..3832dfa 100644 --- a/FoodOrders/FoodOrders/FormShop.Designer.cs +++ b/FoodOrders/FoodOrders/FormShop.Designer.cs @@ -41,6 +41,8 @@ this.textBoxAddress = new System.Windows.Forms.TextBox(); this.labelDateOfOpening = new System.Windows.Forms.Label(); this.dateTimePicker = new System.Windows.Forms.DateTimePicker(); + this.textBoxCapacity = new System.Windows.Forms.TextBox(); + this.labelCapacity = new System.Windows.Forms.Label(); this.groupBox.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.SuspendLayout(); @@ -157,11 +159,31 @@ this.dateTimePicker.Size = new System.Drawing.Size(200, 23); this.dateTimePicker.TabIndex = 6; // + // textBoxCapacity + // + this.textBoxCapacity.Location = new System.Drawing.Point(417, 57); + this.textBoxCapacity.Margin = new System.Windows.Forms.Padding(2); + this.textBoxCapacity.Name = "textBoxCapacity"; + this.textBoxCapacity.Size = new System.Drawing.Size(200, 23); + this.textBoxCapacity.TabIndex = 10; + // + // labelCapacity + // + this.labelCapacity.AutoSize = true; + this.labelCapacity.Location = new System.Drawing.Point(324, 60); + this.labelCapacity.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.labelCapacity.Name = "labelCapacity"; + this.labelCapacity.Size = new System.Drawing.Size(80, 15); + this.labelCapacity.TabIndex = 9; + this.labelCapacity.Text = "Вместимость"; + // // FormShop // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(639, 335); + this.Controls.Add(this.textBoxCapacity); + this.Controls.Add(this.labelCapacity); this.Controls.Add(this.dateTimePicker); this.Controls.Add(this.labelDateOfOpening); this.Controls.Add(this.textBoxAddress); @@ -194,5 +216,7 @@ private TextBox textBoxAddress; private Label labelDateOfOpening; private DateTimePicker dateTimePicker; + private TextBox textBoxCapacity; + private Label labelCapacity; } } \ No newline at end of file diff --git a/FoodOrders/FoodOrders/FormShop.cs b/FoodOrders/FoodOrders/FormShop.cs index 0a43012..199ca9b 100644 --- a/FoodOrders/FoodOrders/FormShop.cs +++ b/FoodOrders/FoodOrders/FormShop.cs @@ -35,6 +35,7 @@ namespace FoodOrdersView textBoxName.Text = view.ShopName; textBoxAddress.Text = view.Address; dateTimePicker.Value = view.DateOfOpening; + textBoxCapacity.Text = view.Capacity.ToString(); _shopDishes = view.ShopDishes ?? new Dictionary(); LoadData(); } @@ -81,6 +82,11 @@ namespace FoodOrdersView MessageBoxIcon.Error); return; } + if (string.IsNullOrEmpty(textBoxCapacity.Text) || dataGridView.Rows.Cast().Sum(x => Convert.ToInt32(x.Cells[2].Value)) > Convert.ToInt32(textBoxCapacity.Text)) + { + MessageBox.Show("Заполните вместимость корректно", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } _logger.LogInformation("Сохранение магазина"); try { @@ -90,7 +96,8 @@ namespace FoodOrdersView ShopName = textBoxName.Text, Address = textBoxAddress.Text, DateOfOpening = dateTimePicker.Value.Date, - ShopDishes = _shopDishes + ShopDishes = _shopDishes, + Capacity = Convert.ToInt32(textBoxCapacity.Text) }; var operationResult = _id.HasValue ? _logicS.Update(model) : _logicS.Create(model); if (!operationResult) diff --git a/FoodOrders/FoodOrders/FormShops.Designer.cs b/FoodOrders/FoodOrders/FormShops.Designer.cs index 8994dc4..460e5b4 100644 --- a/FoodOrders/FoodOrders/FormShops.Designer.cs +++ b/FoodOrders/FoodOrders/FormShops.Designer.cs @@ -33,6 +33,7 @@ this.buttonDelete = new System.Windows.Forms.Button(); this.buttonUpdate = new System.Windows.Forms.Button(); this.dataGridView = new System.Windows.Forms.DataGridView(); + this.buttonSellDishes = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.SuspendLayout(); // @@ -85,11 +86,23 @@ this.dataGridView.Size = new System.Drawing.Size(404, 342); this.dataGridView.TabIndex = 4; // + // buttonSellDishes + // + this.buttonSellDishes.Location = new System.Drawing.Point(409, 264); + this.buttonSellDishes.Margin = new System.Windows.Forms.Padding(2); + this.buttonSellDishes.Name = "buttonSellDishes"; + this.buttonSellDishes.Size = new System.Drawing.Size(133, 23); + this.buttonSellDishes.TabIndex = 6; + this.buttonSellDishes.Text = "Продажа блюд"; + this.buttonSellDishes.UseVisualStyleBackColor = true; + this.buttonSellDishes.Click += new System.EventHandler(this.ButtonSellDishes_Click); + // // FormShops // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(554, 342); + this.Controls.Add(this.buttonSellDishes); this.Controls.Add(this.dataGridView); this.Controls.Add(this.buttonUpdate); this.Controls.Add(this.buttonDelete); @@ -110,5 +123,6 @@ private Button buttonDelete; private Button buttonUpdate; private DataGridView dataGridView; + private Button buttonSellDishes; } } \ No newline at end of file diff --git a/FoodOrders/FoodOrders/FormShops.cs b/FoodOrders/FoodOrders/FormShops.cs index 10fd11a..da50b31 100644 --- a/FoodOrders/FoodOrders/FormShops.cs +++ b/FoodOrders/FoodOrders/FormShops.cs @@ -95,5 +95,16 @@ namespace FoodOrdersView } } } + private void ButtonSellDishes_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormSellDishes)); + if (service is FormSellDishes form) + { + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } } } diff --git a/FoodOrders/FoodOrders/Program.cs b/FoodOrders/FoodOrders/Program.cs index d148637..486e4d3 100644 --- a/FoodOrders/FoodOrders/Program.cs +++ b/FoodOrders/FoodOrders/Program.cs @@ -54,6 +54,7 @@ namespace FoodOrdersView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file diff --git a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/OrderLogic.cs b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/OrderLogic.cs index 4ae8577..e905f6f 100644 --- a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/OrderLogic.cs @@ -12,10 +12,14 @@ namespace FoodOrdersBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + private readonly IShopLogic _logicS; + private readonly IDishStorage _dishStorage; + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IShopLogic logicS, IDishStorage dishStorage) { _logger = logger; _orderStorage = orderStorage; + _logicS = logicS; + _dishStorage = dishStorage; } public List? ReadList(OrderSearchModel? model) @@ -110,6 +114,10 @@ namespace FoodOrdersBusinessLogic.BusinessLogics { model.DateImplement = viewModel.DateImplement; } + if (model.Status == OrderStatus.Выдан && !_logicS.AddDishes(_dishStorage.GetElement(new DishSearchModel { Id = viewModel.DishId })!, viewModel.Count)) + { + throw new Exception("В магазинах нет места под блюда из заказа."); + } CheckModel(model, false); if (_orderStorage.Update(model) == null) { diff --git a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs index d78a7ef..dfd1958 100644 --- a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs +++ b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs @@ -60,6 +60,10 @@ namespace FoodOrdersBusinessLogic.BusinessLogics _logger.LogWarning("Shop not found"); return false; } + if (element.Capacity - element.ShopDishes.Sum(x => x.Value.Item2) < count) + { + throw new InvalidOperationException("В магазине нет места под такое количество блюд"); + } if (element.ShopDishes.ContainsKey(dish.Id)) { element.ShopDishes[dish.Id] = (dish, element.ShopDishes[dish.Id].Item2 + count); @@ -74,7 +78,8 @@ namespace FoodOrdersBusinessLogic.BusinessLogics ShopName = element.ShopName, Address = element.Address, DateOfOpening = element.DateOfOpening, - ShopDishes = element.ShopDishes + ShopDishes = element.ShopDishes, + Capacity = element.Capacity }); return true; } @@ -144,5 +149,36 @@ namespace FoodOrdersBusinessLogic.BusinessLogics throw new InvalidOperationException("Магазин с таким названием уже есть"); } } + public bool SellDishes(IDishModel dish, int count) + { + return _shopStorage.SellDishes(dish, count); + } + public bool AddDishes(IDishModel dish, int count) + { + if (dish == null || count < 1) + { + return false; + } + List shopsList = _shopStorage.GetFullList(); + if (shopsList.Sum(x => x.Capacity) - shopsList.Sum(x => x.ShopDishes.Sum(y => y.Value.Item2)) < count) + { + return false; + } + foreach (ShopViewModel shop in shopsList) + { + int emptySpace = shop.Capacity - shop.ShopDishes.Sum(x => x.Value.Item2); + if (emptySpace < count) + { + DeliveryDishes(new ShopSearchModel { Id = shop.Id }, dish, emptySpace); + count -= emptySpace; + } + else + { + DeliveryDishes(new ShopSearchModel { Id = shop.Id }, dish, count); + break; + } + } + return true; + } } } diff --git a/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs b/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs index 75da34d..d198eb9 100644 --- a/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs +++ b/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs @@ -9,5 +9,6 @@ namespace FoodOrdersContracts.BindingModels public string Address { get; set; } = string.Empty; public DateTime DateOfOpening { get; set; } = DateTime.Now; public Dictionary ShopDishes { get; set; } = new(); + public int Capacity { get; set; } } } diff --git a/FoodOrders/FoodOrdersContracts/BuisnessLogicsContracts/IShopLogic.cs b/FoodOrders/FoodOrdersContracts/BuisnessLogicsContracts/IShopLogic.cs index 061a8ad..073c3cb 100644 --- a/FoodOrders/FoodOrdersContracts/BuisnessLogicsContracts/IShopLogic.cs +++ b/FoodOrders/FoodOrdersContracts/BuisnessLogicsContracts/IShopLogic.cs @@ -13,5 +13,7 @@ namespace FoodOrdersContracts.BusinessLogicsContracts bool Update(ShopBindingModel model); bool Delete(ShopBindingModel model); bool DeliveryDishes(ShopSearchModel model, IDishModel dish, int count); + bool SellDishes(IDishModel dish, int count); + bool AddDishes(IDishModel dish, int count); } } diff --git a/FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs b/FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs index c444d49..fb7ab20 100644 --- a/FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs +++ b/FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs @@ -1,6 +1,7 @@ using FoodOrdersContracts.BindingModels; using FoodOrdersContracts.SearchModels; using FoodOrdersContracts.ViewModels; +using FoodOrdersDataModels.Models; namespace FoodOrdersContracts.StoragesContracts { @@ -12,5 +13,6 @@ namespace FoodOrdersContracts.StoragesContracts ShopViewModel? Insert(ShopBindingModel model); ShopViewModel? Update(ShopBindingModel model); ShopViewModel? Delete(ShopBindingModel model); + bool SellDishes(IDishModel dish, int count); } } diff --git a/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs b/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs index b60ab86..466d5ed 100644 --- a/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs +++ b/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs @@ -12,6 +12,8 @@ namespace FoodOrdersContracts.ViewModels public string Address { get; set; } = string.Empty; [DisplayName("Дата открытия")] public DateTime DateOfOpening { get; set; } = DateTime.Now; + [DisplayName("Вместимость")] + public int Capacity { get; set; } = 0; public Dictionary ShopDishes { get; set; } = new(); } } diff --git a/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs b/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs index 7e46be9..18ec475 100644 --- a/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs +++ b/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs @@ -6,5 +6,6 @@ string Address { get; } DateTime DateOfOpening { get; } Dictionary ShopDishes { get; } + int Capacity { get; } } } diff --git a/FoodOrders/FoodOrdersFileImplement/DataFileSingleton.cs b/FoodOrders/FoodOrdersFileImplement/DataFileSingleton.cs index b3e5803..2467730 100644 --- a/FoodOrders/FoodOrdersFileImplement/DataFileSingleton.cs +++ b/FoodOrders/FoodOrdersFileImplement/DataFileSingleton.cs @@ -8,9 +8,11 @@ namespace FoodOrdersFileImplement private readonly string ComponentFileName = "Component.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string DishFileName = "Dish.xml"; + private readonly string ShopFileName = "Shop.xml"; public List Components { get; private set; } public List Orders { get; private set; } public List Dishes { get; private set; } + public List Shops { get; private set; } public static DataFileSingleton GetInstance() { if (instance == null) @@ -22,11 +24,13 @@ namespace FoodOrdersFileImplement public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); public void SaveDishes() => SaveData(Dishes, DishFileName, "Dishes", 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)!)!; Dishes = LoadData(DishFileName, "Dish", x => Dish.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/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs b/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..accb880 --- /dev/null +++ b/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs @@ -0,0 +1,123 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.SearchModels; +using FoodOrdersContracts.StoragesContracts; +using FoodOrdersContracts.ViewModels; +using FoodOrdersDataModels.Models; +using FoodOrdersFileImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FoodOrdersFileImplement.Implements +{ + public class ShopStorage : IShopStorage + { + private readonly DataFileSingleton source; + public ShopStorage() + { + source = DataFileSingleton.GetInstance(); + } + 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 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 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 List GetFullList() + { + return source.Shops.Select(x => x.GetViewModel).ToList(); + } + + 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 bool SellDishes(IDishModel dish, int count) + { + if (dish == null || count < 1) return false; + List shopsWithDish = source.Shops.Where(x => x.ShopDishes.ContainsKey(dish.Id)).ToList(); + if (shopsWithDish.Sum(x => x.ShopDishes[dish.Id].Item2) < count) + { + return false; + } + foreach(var shop in shopsWithDish) + { + int dishInShopCount = shop.ShopDishes[dish.Id].Item2; + if(count - dishInShopCount >= 0) + { + count -= dishInShopCount; + shop.ShopDishes.Remove(dish.Id); + } + else + { + shop.ShopDishes[dish.Id] = (dish, shop.ShopDishes[dish.Id].Item2 - count); + count = 0; + } + Update(new ShopBindingModel + { + Id = shop.Id, + ShopName = shop.ShopName, + Address = shop.Address, + DateOfOpening = shop.DateOfOpening, + ShopDishes = shop.ShopDishes, + Capacity = shop.Capacity + }); + if (count == 0) break; + } + return true; + } + } +} diff --git a/FoodOrders/FoodOrdersFileImplement/Models/Shop.cs b/FoodOrders/FoodOrdersFileImplement/Models/Shop.cs new file mode 100644 index 0000000..62ff05f --- /dev/null +++ b/FoodOrders/FoodOrdersFileImplement/Models/Shop.cs @@ -0,0 +1,97 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.ViewModels; +using FoodOrdersDataModels.Models; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace FoodOrdersFileImplement.Models +{ + public class Shop : IShopModel + { + public string ShopName { get; private set; } = string.Empty; + public string Address { get; private set; } = string.Empty; + public DateTime DateOfOpening { get; private set; } = DateTime.Now; + public int Capacity { get; private set; } = 0; + public int Id { get; private set; } + public Dictionary Dishes { get; private set; } = new(); + public Dictionary? _shopDishes = null; + public Dictionary ShopDishes + { + get + { + if (_shopDishes == null) + { + var source = DataFileSingleton.GetInstance(); + _shopDishes = Dishes.ToDictionary(x => x.Key, y => + ((source.Dishes.FirstOrDefault(z => z.Id == y.Key) as IDishModel)!, y.Value)); + } + return _shopDishes; + } + } + public static Shop? Create(ShopBindingModel? model) + { + if (model == null) + { + return null; + } + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOfOpening = model.DateOfOpening, + Dishes = model.ShopDishes.ToDictionary(x => x.Key, x => x.Value.Item2), + Capacity = model.Capacity + }; + } + 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, + DateOfOpening = Convert.ToDateTime(element.Element("DateOfOpening")!.Value), + Dishes = element.Element("ShopDishes")!.Elements("ShopDish").ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value)), + Capacity = Convert.ToInt32(element.Element("Capacity")!.Value) + }; + } + public void Update(ShopBindingModel? model) + { + if (model == null) + { + return; + } + ShopName = model.ShopName; + Address = model.Address; + DateOfOpening = model.DateOfOpening; + Dishes = model.ShopDishes.ToDictionary(x => x.Key, x => x.Value.Item2); + Capacity = model.Capacity; + } + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOfOpening = DateOfOpening, + ShopDishes = ShopDishes, + Capacity = Capacity + }; + public XElement GetXElement => new("Shop", + new XAttribute("Id", Id), + new XElement("ShopName", ShopName), + new XElement("Address", Address), + new XElement("DateOfOpening", DateOfOpening.ToString()), + new XElement("ShopDishes", Dishes.Select(x => new XElement("ShopDish", new XElement("Key", x.Key), new XElement("Value", x.Value))).ToArray()), + new XElement("Capacity",Capacity.ToString())); + } +} diff --git a/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs b/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs index f8f414a..b39f37c 100644 --- a/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs +++ b/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs @@ -3,6 +3,7 @@ using FoodOrdersContracts.SearchModels; using FoodOrdersContracts.StoragesContracts; using FoodOrdersContracts.ViewModels; using FoodOrdersListImplement.Models; +using FoodOrdersDataModels.Models; namespace FoodOrdersListImplement.Implements { @@ -96,5 +97,9 @@ namespace FoodOrdersListImplement.Implements } return null; } + public bool SellDishes(IDishModel dish, int count) + { + throw new NotImplementedException(); + } } } diff --git a/FoodOrders/FoodOrdersListImplement/Models/Shop.cs b/FoodOrders/FoodOrdersListImplement/Models/Shop.cs index 04d3119..c23aac9 100644 --- a/FoodOrders/FoodOrdersListImplement/Models/Shop.cs +++ b/FoodOrders/FoodOrdersListImplement/Models/Shop.cs @@ -13,6 +13,7 @@ namespace FoodOrdersListImplement.Models public string Address { get; private set; } = string.Empty; public DateTime DateOfOpening { get; private set; } = DateTime.Now; public Dictionary ShopDishes { get; private set; } = new Dictionary(); + public int Capacity { get; private set; } = 0; public static Shop? Create(ShopBindingModel? model) { if (model == null) @@ -25,7 +26,8 @@ namespace FoodOrdersListImplement.Models ShopName = model.ShopName, Address = model.Address, DateOfOpening = model.DateOfOpening, - ShopDishes = model.ShopDishes + ShopDishes = model.ShopDishes, + Capacity = model.Capacity }; } public void Update(ShopBindingModel? model) @@ -38,6 +40,7 @@ namespace FoodOrdersListImplement.Models Address = model.Address; DateOfOpening = model.DateOfOpening; ShopDishes = model.ShopDishes; + Capacity = model.Capacity; } public ShopViewModel GetViewModel => new() { @@ -45,7 +48,8 @@ namespace FoodOrdersListImplement.Models ShopName = ShopName, Address = Address, DateOfOpening = DateOfOpening, - ShopDishes = ShopDishes + ShopDishes = ShopDishes, + Capacity = Capacity }; } }