From 4211c2355e43e867f68ee42d5a2b7a38b941effc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9F=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D1=86=D0=B5=D0=B2?= Date: Sun, 24 Mar 2024 22:19:09 +0400 Subject: [PATCH 1/8] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FoodOrders/FoodOrders.sln | 8 +++++++- FoodOrders/FoodOrdersView/FormMain.cs | 2 +- FoodOrders/FoodOrdersView/FormMain.designer.cs | 16 ++++++++-------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/FoodOrders/FoodOrders.sln b/FoodOrders/FoodOrders.sln index 1404a36..b6f4886 100644 --- a/FoodOrders/FoodOrders.sln +++ b/FoodOrders/FoodOrders.sln @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.7.34221.43 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodOrdersView", "FoodOrdersView\FoodOrdersView.csproj", "{C61B8C6C-4777-4AB5-854F-55EA1F16622C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FoodOrdersView", "FoodOrdersView\FoodOrdersView.csproj", "{C61B8C6C-4777-4AB5-854F-55EA1F16622C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FoodOrdersListImplement", "FoodOrdersListImplement\FoodOrdersListImplement.csproj", "{4240E07C-4AD6-468D-87D9-6EB713D86638}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +17,10 @@ Global {C61B8C6C-4777-4AB5-854F-55EA1F16622C}.Debug|Any CPU.Build.0 = Debug|Any CPU {C61B8C6C-4777-4AB5-854F-55EA1F16622C}.Release|Any CPU.ActiveCfg = Release|Any CPU {C61B8C6C-4777-4AB5-854F-55EA1F16622C}.Release|Any CPU.Build.0 = Release|Any CPU + {4240E07C-4AD6-468D-87D9-6EB713D86638}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4240E07C-4AD6-468D-87D9-6EB713D86638}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4240E07C-4AD6-468D-87D9-6EB713D86638}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4240E07C-4AD6-468D-87D9-6EB713D86638}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/FoodOrders/FoodOrdersView/FormMain.cs b/FoodOrders/FoodOrdersView/FormMain.cs index 9aa8040..bb69764 100644 --- a/FoodOrders/FoodOrdersView/FormMain.cs +++ b/FoodOrders/FoodOrdersView/FormMain.cs @@ -51,7 +51,7 @@ namespace FoodOrdersView } } - private void МороженоеToolStripMenuItem_Click(object sender, EventArgs e) + private void БлюдоToolStripMenuItem_Click(object sender, EventArgs e) { var service = Program.ServiceProvider?.GetService(typeof(FormDishes)); if (service is FormDishes form) diff --git a/FoodOrders/FoodOrdersView/FormMain.designer.cs b/FoodOrders/FoodOrdersView/FormMain.designer.cs index 1332c55..799780e 100644 --- a/FoodOrders/FoodOrdersView/FormMain.designer.cs +++ b/FoodOrders/FoodOrdersView/FormMain.designer.cs @@ -31,7 +31,7 @@ menuStrip = new MenuStrip(); справочникиToolStripMenuItem = new ToolStripMenuItem(); компонентыToolStripMenuItem = new ToolStripMenuItem(); - мороженоеToolStripMenuItem = new ToolStripMenuItem(); + блюдоToolStripMenuItem = new ToolStripMenuItem(); buttonIssuedOrder = new Button(); buttonOrderReady = new Button(); buttonTakeOrderInWork = new Button(); @@ -55,7 +55,7 @@ // // справочникиToolStripMenuItem // - справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, мороженоеToolStripMenuItem }); + справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, блюдоToolStripMenuItem }); справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem"; справочникиToolStripMenuItem.Size = new Size(117, 24); справочникиToolStripMenuItem.Text = "Справочники"; @@ -67,12 +67,12 @@ компонентыToolStripMenuItem.Text = "Компоненты"; компонентыToolStripMenuItem.Click += КомпонентыToolStripMenuItem_Click; // - // мороженоеToolStripMenuItem + // блюдоToolStripMenuItem // - мороженоеToolStripMenuItem.Name = "мороженоеToolStripMenuItem"; - мороженоеToolStripMenuItem.Size = new Size(224, 26); - мороженоеToolStripMenuItem.Text = "Еда"; - мороженоеToolStripMenuItem.Click += МороженоеToolStripMenuItem_Click; + блюдоToolStripMenuItem.Name = "блюдоToolStripMenuItem"; + блюдоToolStripMenuItem.Size = new Size(224, 26); + блюдоToolStripMenuItem.Text = "Еда"; + блюдоToolStripMenuItem.Click += БлюдоToolStripMenuItem_Click; // // buttonIssuedOrder // @@ -182,7 +182,7 @@ private MenuStrip menuStrip; private ToolStripMenuItem справочникиToolStripMenuItem; private ToolStripMenuItem компонентыToolStripMenuItem; - private ToolStripMenuItem мороженоеToolStripMenuItem; + private ToolStripMenuItem блюдоToolStripMenuItem; private Button buttonIssuedOrder; private Button buttonOrderReady; private Button buttonTakeOrderInWork; From e646a487eaa92b3ab1bbc4d30980e3d75b58e015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9F=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D1=86=D0=B5=D0=B2?= Date: Mon, 25 Mar 2024 00:29:50 +0400 Subject: [PATCH 2/8] =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FoodOrders/FoodOrders.sln | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/FoodOrders/FoodOrders.sln b/FoodOrders/FoodOrders.sln index b6f4886..f2f90ee 100644 --- a/FoodOrders/FoodOrders.sln +++ b/FoodOrders/FoodOrders.sln @@ -7,6 +7,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FoodOrdersView", "FoodOrder EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FoodOrdersListImplement", "FoodOrdersListImplement\FoodOrdersListImplement.csproj", "{4240E07C-4AD6-468D-87D9-6EB713D86638}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FoodOrdersDataModels", "FoodOrdersDataModels\FoodOrdersDataModels.csproj", "{BF8CC26B-802A-4D60-A036-3D973F011EAA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FoodOrdersContracts", "FoodOrdersContracts\FoodOrdersContracts.csproj", "{D8B23BD7-1975-44D8-A092-AAF4D0A3CD56}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FoodOrdersBusinessLogic", "FoodOrdersBusinessLogic\FoodOrdersBusinessLogic.csproj", "{D0A7647D-5976-4D75-A7B5-5258A50D9B56}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +27,18 @@ Global {4240E07C-4AD6-468D-87D9-6EB713D86638}.Debug|Any CPU.Build.0 = Debug|Any CPU {4240E07C-4AD6-468D-87D9-6EB713D86638}.Release|Any CPU.ActiveCfg = Release|Any CPU {4240E07C-4AD6-468D-87D9-6EB713D86638}.Release|Any CPU.Build.0 = Release|Any CPU + {BF8CC26B-802A-4D60-A036-3D973F011EAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BF8CC26B-802A-4D60-A036-3D973F011EAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BF8CC26B-802A-4D60-A036-3D973F011EAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BF8CC26B-802A-4D60-A036-3D973F011EAA}.Release|Any CPU.Build.0 = Release|Any CPU + {D8B23BD7-1975-44D8-A092-AAF4D0A3CD56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8B23BD7-1975-44D8-A092-AAF4D0A3CD56}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8B23BD7-1975-44D8-A092-AAF4D0A3CD56}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8B23BD7-1975-44D8-A092-AAF4D0A3CD56}.Release|Any CPU.Build.0 = Release|Any CPU + {D0A7647D-5976-4D75-A7B5-5258A50D9B56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0A7647D-5976-4D75-A7B5-5258A50D9B56}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0A7647D-5976-4D75-A7B5-5258A50D9B56}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0A7647D-5976-4D75-A7B5-5258A50D9B56}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 2fbd0d71fde890b325c2d1670f1ea16826c2f62f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9F=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D1=86=D0=B5=D0=B2?= Date: Mon, 25 Mar 2024 01:38:54 +0400 Subject: [PATCH 3/8] =?UTF-8?q?=D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=B0=D1=8F?= =?UTF-8?q?=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=201=20(=D0=A1=D0=BB=D0=BE=D0=B6=D0=BD=D0=B0=D1=8F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/ShopLogic.cs | 166 +++++++++++++ .../BindingModels/ShopBindingModel.cs | 21 ++ .../BusinessLogicsContracts/IShopLogic.cs | 22 ++ .../SearchModels/ShopSearchModel.cs | 9 + .../StoragesContracts/IShopStorage.cs | 21 ++ .../ViewModels/ShopViewModel.cs | 25 ++ .../FoodOrdersDataModels/Models/IShopModel.cs | 13 ++ .../DataListSingleton.cs | 2 + .../Implements/ShopStorage.cs | 109 +++++++++ .../FoodOrdersListImplement/Models/Shop.cs | 60 +++++ FoodOrders/FoodOrdersView/FormMain.cs | 18 ++ .../FoodOrdersView/FormMain.designer.cs | 22 +- .../FormMakeShipment.Designer.cs | 153 ++++++++++++ FoodOrders/FoodOrdersView/FormMakeShipment.cs | 116 +++++++++ .../FoodOrdersView/FormMakeShipment.resx | 120 ++++++++++ .../FoodOrdersView/FormShop.Designer.cs | 221 ++++++++++++++++++ FoodOrders/FoodOrdersView/FormShop.cs | 125 ++++++++++ FoodOrders/FoodOrdersView/FormShop.resx | 120 ++++++++++ .../FoodOrdersView/FormShops.Designer.cs | 126 ++++++++++ FoodOrders/FoodOrdersView/FormShops.cs | 104 +++++++++ FoodOrders/FoodOrdersView/FormShops.resx | 120 ++++++++++ FoodOrders/FoodOrdersView/Program.cs | 5 + 22 files changed, 1696 insertions(+), 2 deletions(-) create mode 100644 FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs create mode 100644 FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs create mode 100644 FoodOrders/FoodOrdersContracts/BusinessLogicsContracts/IShopLogic.cs create mode 100644 FoodOrders/FoodOrdersContracts/SearchModels/ShopSearchModel.cs create mode 100644 FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs create mode 100644 FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs create mode 100644 FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs create mode 100644 FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs create mode 100644 FoodOrders/FoodOrdersListImplement/Models/Shop.cs create mode 100644 FoodOrders/FoodOrdersView/FormMakeShipment.Designer.cs create mode 100644 FoodOrders/FoodOrdersView/FormMakeShipment.cs create mode 100644 FoodOrders/FoodOrdersView/FormMakeShipment.resx create mode 100644 FoodOrders/FoodOrdersView/FormShop.Designer.cs create mode 100644 FoodOrders/FoodOrdersView/FormShop.cs create mode 100644 FoodOrders/FoodOrdersView/FormShop.resx create mode 100644 FoodOrders/FoodOrdersView/FormShops.Designer.cs create mode 100644 FoodOrders/FoodOrdersView/FormShops.cs create mode 100644 FoodOrders/FoodOrdersView/FormShops.resx diff --git a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs new file mode 100644 index 0000000..14c24f0 --- /dev/null +++ b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs @@ -0,0 +1,166 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.BusinessLogicsContracts; +using FoodOrdersContracts.SearchModels; +using FoodOrdersContracts.StoragesContracts; +using FoodOrdersContracts.ViewModels; +using FoodOrdersDataModels.Models; +using Microsoft.Extensions.Logging; + +namespace FoodOrdersBusinessLogic.BusinessLogics +{ + 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. ShopName: {ShopName}. Id: {Id}", model?.ShopName, model?.Id); + var list = model == null ? _shopStorage.GetFullList() : _shopStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count: {Count}", list.Count); + return list; + } + + public ShopViewModel? ReadElement(ShopSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ShopName: {ShopName}. Id: {Id}", model.ShopName, model.Id); + var element = _shopStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id: {Id}", element.Id); + return element; + } + + public bool Create(ShopBindingModel model) + { + CheckModel(model); + if (_shopStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Update(ShopBindingModel model) + { + CheckModel(model); + if (_shopStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + + public bool Delete(ShopBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id: {Id}", model.Id); + if (_shopStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public bool MakeShipment(ShopSearchModel shopModel, IDishModel dish, int count) + { + if (shopModel == null) + { + throw new ArgumentNullException(nameof(shopModel)); + } + if (dish == null) + { + throw new ArgumentNullException(nameof(dish)); + } + if (count <= 0) + { + throw new ArgumentException("Количество товаров(мороженого) в магазине должно быть больше нуля", nameof(count)); + } + _logger.LogInformation("MakeShipment(GetElement). ShopName: {ShopName}. Id: {Id}", shopModel.ShopName, shopModel.Id); + var shop = _shopStorage.GetElement(shopModel); + if (shop == null) + { + _logger.LogWarning("MakeShipment(GetElement). Element not found"); + return false; + } + if (shop.ShopDishs.ContainsKey(dish.Id)) + { + var shopIC = shop.ShopDishs[dish.Id]; + shopIC.Item2 += count; + shop.ShopDishs[dish.Id] = shopIC; + _logger.LogInformation("MakeShipment. Added {count} '{dish}' to '{ShopName}' shop", count, dish.DishName, + shop.ShopName); + } + else + { + shop.ShopDishs.Add(dish.Id, (dish, count)); + _logger.LogInformation("MakeShipment. Added {count} new '{dish}' to '{ShopName}' shop", count, dish.DishName, + shop.ShopName); + } + if (_shopStorage.Update(new ShopBindingModel() + { + Id = shop.Id, + ShopName = shop.ShopName, + Address = shop.Address, + DateOpening = shop.DateOpening, + ShopDishs = shop.ShopDishs, + }) == null) + { + _logger.LogWarning("MakeShipment. Update operation failed"); + return false; + } + return true; + } + + private void CheckModel(ShopBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.ShopName)) + { + throw new ArgumentNullException("Нет названия магазина", nameof(model.ShopName)); + } + if (string.IsNullOrEmpty(model.Address)) + { + throw new ArgumentNullException("Нет адреса магазина", nameof(model.Address)); + } + _logger.LogInformation("Shop. ShopName: {ShopName}. Address: {Address}. Id: {Id}", model.ShopName, model.Address, model.Id); + var element = _shopStorage.GetElement(new ShopSearchModel + { + ShopName = model.ShopName + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Магазин с таким названием уже есть"); + } + } + } +} diff --git a/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs b/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs new file mode 100644 index 0000000..cc31939 --- /dev/null +++ b/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs @@ -0,0 +1,21 @@ +using FoodOrdersDataModels.Models; + +namespace FoodOrdersContracts.BindingModels +{ + public class ShopBindingModel : IShopModel + { + public int Id { get; set; } + + public string ShopName { get; set; } = string.Empty; + + public string Address { get; set; } = string.Empty; + + public DateTime DateOpening { get; set; } = DateTime.Now; + + public Dictionary ShopDishs + { + get; + set; + } = new(); + } +} diff --git a/FoodOrders/FoodOrdersContracts/BusinessLogicsContracts/IShopLogic.cs b/FoodOrders/FoodOrdersContracts/BusinessLogicsContracts/IShopLogic.cs new file mode 100644 index 0000000..e405f1b --- /dev/null +++ b/FoodOrders/FoodOrdersContracts/BusinessLogicsContracts/IShopLogic.cs @@ -0,0 +1,22 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.SearchModels; +using FoodOrdersContracts.ViewModels; +using FoodOrdersDataModels.Models; + +namespace FoodOrdersContracts.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 MakeShipment(ShopSearchModel shopModel, IDishModel dish, int count); + } +} diff --git a/FoodOrders/FoodOrdersContracts/SearchModels/ShopSearchModel.cs b/FoodOrders/FoodOrdersContracts/SearchModels/ShopSearchModel.cs new file mode 100644 index 0000000..6546192 --- /dev/null +++ b/FoodOrders/FoodOrdersContracts/SearchModels/ShopSearchModel.cs @@ -0,0 +1,9 @@ +namespace FoodOrdersContracts.SearchModels +{ + public class ShopSearchModel + { + public int? Id { get; set; } + + public string? ShopName { get; set; } + } +} diff --git a/FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs b/FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs new file mode 100644 index 0000000..affa849 --- /dev/null +++ b/FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs @@ -0,0 +1,21 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.SearchModels; +using FoodOrdersContracts.ViewModels; + +namespace FoodOrdersContracts.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); + } +} diff --git a/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs b/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs new file mode 100644 index 0000000..22e3f12 --- /dev/null +++ b/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs @@ -0,0 +1,25 @@ +using FoodOrdersDataModels.Models; +using System.ComponentModel; + +namespace FoodOrdersContracts.ViewModels +{ + public class ShopViewModel : IShopModel + { + public int Id { get; set; } + + [DisplayName("Название магазина")] + public string ShopName { get; set; } = string.Empty; + + [DisplayName("Адрес")] + public string Address { get; set; } = string.Empty; + + [DisplayName("Дата открытия")] + public DateTime DateOpening { get; set; } = DateTime.Now; + + public Dictionary ShopDishs + { + get; + set; + } = new(); + } +} diff --git a/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs b/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs new file mode 100644 index 0000000..3a65e5b --- /dev/null +++ b/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs @@ -0,0 +1,13 @@ +namespace FoodOrdersDataModels.Models +{ + public interface IShopModel : IId + { + string ShopName { get; } + + string Address { get; } + + DateTime DateOpening { get; } + + Dictionary ShopDishs { get; } + } +} diff --git a/FoodOrders/FoodOrdersListImplement/DataListSingleton.cs b/FoodOrders/FoodOrdersListImplement/DataListSingleton.cs index b6d98dc..29713ec 100644 --- a/FoodOrders/FoodOrdersListImplement/DataListSingleton.cs +++ b/FoodOrders/FoodOrdersListImplement/DataListSingleton.cs @@ -11,12 +11,14 @@ namespace FoodOrdersListImplement public List Orders { get; set; } public List Dishes { get; set; } + public List Shops { get; set; } private DataListSingleton() { Components = new List(); Orders = new List(); Dishes = new List(); + Shops = new List(); } public static DataListSingleton GetInstance() diff --git a/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs b/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..bdf6d75 --- /dev/null +++ b/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs @@ -0,0 +1,109 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.SearchModels; +using FoodOrdersContracts.StoragesContracts; +using FoodOrdersContracts.ViewModels; +using FoodOrdersListImplement.Models; + +namespace FoodOrdersListImplement.Implements +{ + public class ShopStorage : IShopStorage + { + private readonly DataListSingleton _source; + + public ShopStorage() + { + _source = DataListSingleton.GetInstance(); + } + + public List GetFullList() + { + var result = new List(); + foreach (var shop in _source.Shops) + { + result.Add(shop.GetViewModel); + } + return result; + } + + public List GetFilteredList(ShopSearchModel model) + { + var result = new List(); + if (string.IsNullOrEmpty(model.ShopName)) + { + return result; + } + foreach (var shop in _source.Shops) + { + if (shop.ShopName.Contains(model.ShopName)) + { + result.Add(shop.GetViewModel); + } + } + return result; + } + + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue) + { + return null; + } + foreach (var shop in _source.Shops) + { + if ((!string.IsNullOrEmpty(model.ShopName) && + shop.ShopName == model.ShopName) || + (model.Id.HasValue && shop.Id == model.Id)) + { + return shop.GetViewModel; + } + } + return null; + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + model.Id = 1; + foreach (var shop in _source.Shops) + { + if (model.Id <= shop.Id) + { + model.Id = shop.Id + 1; + } + } + var newShop = Shop.Create(model); + if (newShop == null) + { + return null; + } + _source.Shops.Add(newShop); + return newShop.GetViewModel; + } + + public ShopViewModel? Update(ShopBindingModel model) + { + foreach (var shop in _source.Shops) + { + if (shop.Id == model.Id) + { + shop.Update(model); + return shop.GetViewModel; + } + } + return null; + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + for (int i = 0; i < _source.Shops.Count; ++i) + { + if (_source.Shops[i].Id == model.Id) + { + var element = _source.Shops[i]; + _source.Shops.RemoveAt(i); + return element.GetViewModel; + } + } + return null; + } + } +} diff --git a/FoodOrders/FoodOrdersListImplement/Models/Shop.cs b/FoodOrders/FoodOrdersListImplement/Models/Shop.cs new file mode 100644 index 0000000..8d9b1e9 --- /dev/null +++ b/FoodOrders/FoodOrdersListImplement/Models/Shop.cs @@ -0,0 +1,60 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.ViewModels; +using FoodOrdersDataModels.Models; + +namespace FoodOrdersListImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + + public string ShopName { get; private set; } = string.Empty; + + public string Address { get; private set; } = string.Empty; + + public DateTime DateOpening { get; private set; } + + public Dictionary ShopDishs + { + 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, + ShopDishs = model.ShopDishs + }; + } + + public void Update(ShopBindingModel? model) + { + if (model == null) + { + return; + } + ShopName = model.ShopName; + Address = model.Address; + DateOpening = model.DateOpening; + ShopDishs = model.ShopDishs; + } + + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpening = DateOpening, + ShopDishs = ShopDishs + }; + } +} diff --git a/FoodOrders/FoodOrdersView/FormMain.cs b/FoodOrders/FoodOrdersView/FormMain.cs index bb69764..7f53cc2 100644 --- a/FoodOrders/FoodOrdersView/FormMain.cs +++ b/FoodOrders/FoodOrdersView/FormMain.cs @@ -144,5 +144,23 @@ namespace FoodOrdersView { LoadData(); } + + private void магазиныToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormShops)); + if (service is FormShops form) + { + form.ShowDialog(); + } + } + + private void пополнениеМагазинаToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormMakeShipment)); + if (service is FormMakeShipment form) + { + form.ShowDialog(); + } + } } } \ No newline at end of file diff --git a/FoodOrders/FoodOrdersView/FormMain.designer.cs b/FoodOrders/FoodOrdersView/FormMain.designer.cs index 799780e..15f6287 100644 --- a/FoodOrders/FoodOrdersView/FormMain.designer.cs +++ b/FoodOrders/FoodOrdersView/FormMain.designer.cs @@ -32,6 +32,8 @@ справочникиToolStripMenuItem = new ToolStripMenuItem(); компонентыToolStripMenuItem = new ToolStripMenuItem(); блюдоToolStripMenuItem = new ToolStripMenuItem(); + магазиныToolStripMenuItem = new ToolStripMenuItem(); + пополнениеМагазинаToolStripMenuItem = new ToolStripMenuItem(); buttonIssuedOrder = new Button(); buttonOrderReady = new Button(); buttonTakeOrderInWork = new Button(); @@ -45,7 +47,7 @@ // menuStrip // menuStrip.ImageScalingSize = new Size(20, 20); - menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem }); + menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, пополнениеМагазинаToolStripMenuItem }); menuStrip.Location = new Point(0, 0); menuStrip.Name = "menuStrip"; menuStrip.Padding = new Padding(8, 3, 0, 3); @@ -55,7 +57,7 @@ // // справочникиToolStripMenuItem // - справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, блюдоToolStripMenuItem }); + справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, блюдоToolStripMenuItem, магазиныToolStripMenuItem }); справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem"; справочникиToolStripMenuItem.Size = new Size(117, 24); справочникиToolStripMenuItem.Text = "Справочники"; @@ -74,6 +76,20 @@ блюдоToolStripMenuItem.Text = "Еда"; блюдоToolStripMenuItem.Click += БлюдоToolStripMenuItem_Click; // + // магазиныToolStripMenuItem + // + магазиныToolStripMenuItem.Name = "магазиныToolStripMenuItem"; + магазиныToolStripMenuItem.Size = new Size(224, 26); + магазиныToolStripMenuItem.Text = "Магазины"; + магазиныToolStripMenuItem.Click += магазиныToolStripMenuItem_Click; + // + // пополнениеМагазинаToolStripMenuItem + // + пополнениеМагазинаToolStripMenuItem.Name = "пополнениеМагазинаToolStripMenuItem"; + пополнениеМагазинаToolStripMenuItem.Size = new Size(182, 24); + пополнениеМагазинаToolStripMenuItem.Text = "Пополнение магазина"; + пополнениеМагазинаToolStripMenuItem.Click += пополнениеМагазинаToolStripMenuItem_Click; + // // buttonIssuedOrder // buttonIssuedOrder.Anchor = AnchorStyles.Top | AnchorStyles.Right; @@ -189,6 +205,8 @@ private Button buttonCreateOrder; private DataGridView dataGridView; private Button buttonUpd; + private ToolStripMenuItem магазиныToolStripMenuItem; + private ToolStripMenuItem пополнениеМагазинаToolStripMenuItem; } } diff --git a/FoodOrders/FoodOrdersView/FormMakeShipment.Designer.cs b/FoodOrders/FoodOrdersView/FormMakeShipment.Designer.cs new file mode 100644 index 0000000..1fd0342 --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormMakeShipment.Designer.cs @@ -0,0 +1,153 @@ +namespace FoodOrdersView +{ + partial class FormMakeShipment + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + labelShop = new Label(); + comboBoxShop = new ComboBox(); + labelDish = new Label(); + comboBoxDish = new ComboBox(); + labelCount = new Label(); + textBoxCount = new TextBox(); + buttonSave = new Button(); + buttonCancel = new Button(); + SuspendLayout(); + // + // labelShop + // + labelShop.AutoSize = true; + labelShop.Location = new Point(14, 13); + labelShop.Margin = new Padding(4, 0, 4, 0); + labelShop.Name = "labelShop"; + labelShop.Size = new Size(60, 15); + labelShop.TabIndex = 2; + labelShop.Text = "Магазин :"; + // + // comboBoxShop + // + comboBoxShop.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxShop.FormattingEnabled = true; + comboBoxShop.Location = new Point(102, 10); + comboBoxShop.Margin = new Padding(4, 3, 4, 3); + comboBoxShop.Name = "comboBoxShop"; + comboBoxShop.Size = new Size(252, 23); + comboBoxShop.TabIndex = 5; + // + // labelDish + // + labelDish.AutoSize = true; + labelDish.Location = new Point(14, 48); + labelDish.Margin = new Padding(4, 0, 4, 0); + labelDish.Name = "labelDish"; + labelDish.Size = new Size(80, 15); + labelDish.TabIndex = 6; + labelDish.Text = "Блюдо :"; + // + // comboBoxDish + // + comboBoxDish.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxDish.FormattingEnabled = true; + comboBoxDish.Location = new Point(102, 44); + comboBoxDish.Margin = new Padding(4, 3, 4, 3); + comboBoxDish.Name = "comboBoxDish"; + comboBoxDish.Size = new Size(252, 23); + comboBoxDish.TabIndex = 7; + // + // labelCount + // + labelCount.AutoSize = true; + labelCount.Location = new Point(14, 83); + labelCount.Margin = new Padding(4, 0, 4, 0); + labelCount.Name = "labelCount"; + labelCount.Size = new Size(78, 15); + labelCount.TabIndex = 8; + labelCount.Text = "Количество :"; + // + // textBoxCount + // + textBoxCount.Location = new Point(102, 80); + textBoxCount.Margin = new Padding(4, 3, 4, 3); + textBoxCount.Name = "textBoxCount"; + textBoxCount.Size = new Size(252, 23); + textBoxCount.TabIndex = 9; + // + // buttonSave + // + buttonSave.Location = new Point(160, 112); + buttonSave.Margin = new Padding(4, 3, 4, 3); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(88, 27); + buttonSave.TabIndex = 10; + buttonSave.Text = "Сохранить"; + buttonSave.UseVisualStyleBackColor = true; + buttonSave.Click += ButtonSave_Click; + // + // buttonCancel + // + buttonCancel.Location = new Point(254, 112); + buttonCancel.Margin = new Padding(4, 3, 4, 3); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(88, 27); + buttonCancel.TabIndex = 11; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += ButtonCancel_Click; + // + // FormMakeShipment + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(373, 147); + Controls.Add(buttonCancel); + Controls.Add(buttonSave); + Controls.Add(textBoxCount); + Controls.Add(labelCount); + Controls.Add(comboBoxDish); + Controls.Add(labelDish); + Controls.Add(comboBoxShop); + Controls.Add(labelShop); + Name = "FormMakeShipment"; + StartPosition = FormStartPosition.CenterScreen; + Text = "Пополнение магазина"; + Load += FormMakeShipment_Load; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label labelShop; + private ComboBox comboBoxShop; + private Label labelDish; + private ComboBox comboBoxDish; + private Label labelCount; + private TextBox textBoxCount; + private Button buttonSave; + private Button buttonCancel; + } +} \ No newline at end of file diff --git a/FoodOrders/FoodOrdersView/FormMakeShipment.cs b/FoodOrders/FoodOrdersView/FormMakeShipment.cs new file mode 100644 index 0000000..1134ff0 --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormMakeShipment.cs @@ -0,0 +1,116 @@ +using FoodOrdersContracts.BusinessLogicsContracts; +using FoodOrdersContracts.SearchModels; +using Microsoft.Extensions.Logging; + +namespace FoodOrdersView +{ + public partial class FormMakeShipment : Form + { + private readonly ILogger _logger; + + private readonly IDishLogic _logicDish; + + private readonly IShopLogic _logicShop; + + public FormMakeShipment(ILogger logger, IDishLogic logicDish, IShopLogic logicShop) + { + InitializeComponent(); + _logger = logger; + _logicDish = logicDish; + _logicShop = logicShop; + } + + private void FormMakeShipment_Load(object sender, EventArgs e) + { + _logger.LogInformation("Ice creams loading"); + try + { + var list = _logicDish.ReadList(null); + if (list != null) + { + comboBoxDish.DisplayMember = "DishName"; + comboBoxDish.ValueMember = "Id"; + comboBoxDish.DataSource = list; + comboBoxDish.SelectedItem = null; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ice creams loading error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + _logger.LogInformation("Shops loading"); + try + { + var list = _logicShop.ReadList(null); + if (list != null) + { + comboBoxShop.DisplayMember = "ShopName"; + comboBoxShop.ValueMember = "Id"; + comboBoxShop.DataSource = list; + comboBoxShop.SelectedItem = null; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Shops loading error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonSave_Click(object sender, EventArgs e) + { + if (comboBoxShop.SelectedValue == null) + { + MessageBox.Show("Выберите магазин", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (comboBoxDish.SelectedValue == null) + { + MessageBox.Show("Выберите блюдо", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (string.IsNullOrEmpty(textBoxCount.Text)) + { + MessageBox.Show("Заполните поле Количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("Shop replenishment"); + try + { + var dish = _logicDish.ReadElement(new DishSearchModel + { Id = Convert.ToInt32(comboBoxDish.SelectedValue) }); + if (dish == null) + { + throw new Exception("Блюдо не найдено."); + } + var operationResult = _logicShop.MakeShipment(new ShopSearchModel + { + Id = Convert.ToInt32(comboBoxShop.SelectedValue) + }, + dish, + 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, "Shop replenishment error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + DialogResult = DialogResult.OK; + Close(); + } + + private void ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/FoodOrders/FoodOrdersView/FormMakeShipment.resx b/FoodOrders/FoodOrdersView/FormMakeShipment.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormMakeShipment.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/FoodOrders/FoodOrdersView/FormShop.Designer.cs b/FoodOrders/FoodOrdersView/FormShop.Designer.cs new file mode 100644 index 0000000..f844a1b --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormShop.Designer.cs @@ -0,0 +1,221 @@ +namespace FoodOrdersView +{ + partial class FormShop + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + labelName = new Label(); + textBoxName = new TextBox(); + labelAddress = new Label(); + textBoxAddress = new TextBox(); + dateTimePicker = new DateTimePicker(); + labelOpeningDate = new Label(); + groupBoxDishs = new GroupBox(); + dataGridView = new DataGridView(); + buttonSave = new Button(); + buttonCancel = new Button(); + ColumnId = new DataGridViewTextBoxColumn(); + ColumnName = new DataGridViewTextBoxColumn(); + ColumnCount = new DataGridViewTextBoxColumn(); + groupBoxDishs.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); + SuspendLayout(); + // + // labelName + // + labelName.AutoSize = true; + labelName.Location = new Point(16, 13); + labelName.Margin = new Padding(5, 0, 5, 0); + labelName.Name = "labelName"; + labelName.Size = new Size(84, 20); + labelName.TabIndex = 1; + labelName.Text = "Название :"; + // + // textBoxName + // + textBoxName.Location = new Point(105, 9); + textBoxName.Margin = new Padding(5, 4, 5, 4); + textBoxName.Name = "textBoxName"; + textBoxName.Size = new Size(287, 27); + textBoxName.TabIndex = 2; + // + // labelAddress + // + labelAddress.AutoSize = true; + labelAddress.Location = new Point(16, 53); + labelAddress.Margin = new Padding(5, 0, 5, 0); + labelAddress.Name = "labelAddress"; + labelAddress.Size = new Size(58, 20); + labelAddress.TabIndex = 3; + labelAddress.Text = "Адрес :"; + // + // textBoxAddress + // + textBoxAddress.Location = new Point(105, 49); + textBoxAddress.Margin = new Padding(5, 4, 5, 4); + textBoxAddress.Name = "textBoxAddress"; + textBoxAddress.Size = new Size(287, 27); + textBoxAddress.TabIndex = 4; + // + // dateTimePicker + // + dateTimePicker.Location = new Point(144, 88); + dateTimePicker.Margin = new Padding(3, 4, 3, 4); + dateTimePicker.Name = "dateTimePicker"; + dateTimePicker.Size = new Size(249, 27); + dateTimePicker.TabIndex = 5; + // + // labelOpeningDate + // + labelOpeningDate.AutoSize = true; + labelOpeningDate.Location = new Point(16, 92); + labelOpeningDate.Margin = new Padding(5, 0, 5, 0); + labelOpeningDate.Name = "labelOpeningDate"; + labelOpeningDate.Size = new Size(117, 20); + labelOpeningDate.TabIndex = 6; + labelOpeningDate.Text = "Дата открытия :"; + // + // groupBoxDishs + // + groupBoxDishs.Controls.Add(dataGridView); + groupBoxDishs.Location = new Point(5, 133); + groupBoxDishs.Margin = new Padding(5, 4, 5, 4); + groupBoxDishs.Name = "groupBoxDishs"; + groupBoxDishs.Padding = new Padding(5, 4, 5, 4); + groupBoxDishs.Size = new Size(536, 384); + groupBoxDishs.TabIndex = 7; + groupBoxDishs.TabStop = false; + groupBoxDishs.Text = "Блюдо"; + // + // dataGridView + // + dataGridView.AllowUserToAddRows = false; + dataGridView.AllowUserToDeleteRows = false; + dataGridView.BackgroundColor = SystemColors.ControlLightLight; + dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dataGridView.Columns.AddRange(new DataGridViewColumn[] { ColumnId, ColumnName, ColumnCount }); + dataGridView.Dock = DockStyle.Left; + dataGridView.Location = new Point(5, 24); + dataGridView.Margin = new Padding(5, 4, 5, 4); + dataGridView.MultiSelect = false; + dataGridView.Name = "dataGridView"; + dataGridView.ReadOnly = true; + dataGridView.RowHeadersVisible = false; + dataGridView.RowHeadersWidth = 51; + dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; + dataGridView.Size = new Size(522, 356); + dataGridView.TabIndex = 0; + // + // buttonSave + // + buttonSave.Location = new Point(291, 525); + buttonSave.Margin = new Padding(5, 4, 5, 4); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(101, 36); + buttonSave.TabIndex = 8; + buttonSave.Text = "Сохранить"; + buttonSave.UseVisualStyleBackColor = true; + buttonSave.Click += ButtonSave_Click; + // + // buttonCancel + // + buttonCancel.Location = new Point(410, 525); + buttonCancel.Margin = new Padding(5, 4, 5, 4); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(101, 36); + buttonCancel.TabIndex = 9; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += ButtonCancel_Click; + // + // ColumnId + // + ColumnId.HeaderText = "Id"; + ColumnId.MinimumWidth = 6; + ColumnId.Name = "ColumnId"; + ColumnId.ReadOnly = true; + ColumnId.Visible = false; + ColumnId.Width = 125; + // + // ColumnName + // + ColumnName.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + ColumnName.HeaderText = "Название блюда"; + ColumnName.MinimumWidth = 6; + ColumnName.Name = "ColumnName"; + ColumnName.ReadOnly = true; + // + // ColumnCount + // + ColumnCount.HeaderText = "Количество"; + ColumnCount.MinimumWidth = 6; + ColumnCount.Name = "ColumnCount"; + ColumnCount.ReadOnly = true; + ColumnCount.Width = 125; + // + // FormShop + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(546, 576); + Controls.Add(buttonCancel); + Controls.Add(buttonSave); + Controls.Add(groupBoxDishs); + Controls.Add(labelOpeningDate); + Controls.Add(dateTimePicker); + Controls.Add(textBoxAddress); + Controls.Add(labelAddress); + Controls.Add(textBoxName); + Controls.Add(labelName); + Margin = new Padding(3, 4, 3, 4); + Name = "FormShop"; + StartPosition = FormStartPosition.CenterScreen; + Text = "Магазин"; + Load += FormShop_Load; + groupBoxDishs.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label labelName; + private TextBox textBoxName; + private Label labelAddress; + private TextBox textBoxAddress; + private DateTimePicker dateTimePicker; + private Label labelOpeningDate; + private GroupBox groupBoxDishs; + private DataGridView dataGridView; + private Button buttonSave; + private Button buttonCancel; + private DataGridViewTextBoxColumn ColumnId; + private DataGridViewTextBoxColumn ColumnName; + private DataGridViewTextBoxColumn ColumnCount; + } +} \ No newline at end of file diff --git a/FoodOrders/FoodOrdersView/FormShop.cs b/FoodOrders/FoodOrdersView/FormShop.cs new file mode 100644 index 0000000..0f61588 --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormShop.cs @@ -0,0 +1,125 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.BusinessLogicsContracts; +using FoodOrdersContracts.SearchModels; +using FoodOrdersDataModels.Models; +using Microsoft.Extensions.Logging; + +namespace FoodOrdersView +{ + public partial class FormShop : Form + { + private readonly ILogger _logger; + + private readonly IShopLogic _logic; + + private int? _id; + + private Dictionary _shopDishs; + + public int Id { set { _id = value; } } + + public FormShop(ILogger logger, IShopLogic logic) + { + InitializeComponent(); + _logger = logger; + _logic = logic; + _shopDishs = new Dictionary(); + } + + private void FormShop_Load(object sender, EventArgs e) + { + if (_id.HasValue) + { + _logger.LogInformation("Shop loading"); + try + { + var view = _logic.ReadElement(new ShopSearchModel { Id = _id.Value }); + if (view != null) + { + textBoxName.Text = view.ShopName; + textBoxAddress.Text = view.Address; + dateTimePicker.Value = view.DateOpening; + _shopDishs = view.ShopDishs ?? new Dictionary(); + LoadData(); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Shop loading error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void LoadData() + { + _logger.LogInformation("Shop ice creams loading"); + try + { + if (_shopDishs != null) + { + dataGridView.Rows.Clear(); + foreach (var dish in _shopDishs) + { + dataGridView.Rows.Add(new object[] { dish.Key, dish.Value.Item1.DishName, dish.Value.Item2 }); + } + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Shop ice creams loading error"); + 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; + } + if (string.IsNullOrEmpty(dateTimePicker.Text)) + { + MessageBox.Show("Заполните дату", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("Shop saving"); + try + { + var model = new ShopBindingModel + { + Id = _id ?? 0, + ShopName = textBoxName.Text, + Address = textBoxAddress.Text, + DateOpening = dateTimePicker.Value, + ShopDishs = _shopDishs + }; + 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, "Shop saving error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/FoodOrders/FoodOrdersView/FormShop.resx b/FoodOrders/FoodOrdersView/FormShop.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormShop.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/FoodOrders/FoodOrdersView/FormShops.Designer.cs b/FoodOrders/FoodOrdersView/FormShops.Designer.cs new file mode 100644 index 0000000..35dda50 --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormShops.Designer.cs @@ -0,0 +1,126 @@ +namespace FoodOrdersView +{ + 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(); + buttonUpd = new Button(); + buttonDel = new Button(); + buttonEdit = new Button(); + buttonAdd = new Button(); + ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); + SuspendLayout(); + // + // dataGridView + // + dataGridView.AllowUserToAddRows = false; + dataGridView.AllowUserToDeleteRows = false; + dataGridView.BackgroundColor = SystemColors.ControlLightLight; + dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dataGridView.Dock = DockStyle.Left; + dataGridView.Location = new Point(0, 0); + dataGridView.Margin = new Padding(4, 3, 4, 3); + dataGridView.MultiSelect = false; + dataGridView.Name = "dataGridView"; + dataGridView.ReadOnly = true; + dataGridView.RowHeadersVisible = false; + dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; + dataGridView.Size = new Size(408, 360); + dataGridView.TabIndex = 2; + // + // buttonUpd + // + buttonUpd.Location = new Point(432, 152); + buttonUpd.Margin = new Padding(4, 3, 4, 3); + buttonUpd.Name = "buttonUpd"; + buttonUpd.Size = new Size(88, 27); + buttonUpd.TabIndex = 12; + buttonUpd.Text = "Обновить"; + buttonUpd.UseVisualStyleBackColor = true; + buttonUpd.Click += ButtonUpd_Click; + // + // buttonDel + // + buttonDel.Location = new Point(432, 105); + buttonDel.Margin = new Padding(4, 3, 4, 3); + buttonDel.Name = "buttonDel"; + buttonDel.Size = new Size(88, 27); + buttonDel.TabIndex = 11; + buttonDel.Text = "Удалить"; + buttonDel.UseVisualStyleBackColor = true; + buttonDel.Click += ButtonDel_Click; + // + // buttonEdit + // + buttonEdit.Location = new Point(432, 58); + buttonEdit.Margin = new Padding(4, 3, 4, 3); + buttonEdit.Name = "buttonEdit"; + buttonEdit.Size = new Size(88, 27); + buttonEdit.TabIndex = 10; + buttonEdit.Text = "Изменить"; + buttonEdit.UseVisualStyleBackColor = true; + buttonEdit.Click += ButtonEdit_Click; + // + // buttonAdd + // + buttonAdd.Location = new Point(432, 14); + buttonAdd.Margin = new Padding(4, 3, 4, 3); + buttonAdd.Name = "buttonAdd"; + buttonAdd.Size = new Size(88, 27); + buttonAdd.TabIndex = 9; + buttonAdd.Text = "Добавить"; + buttonAdd.UseVisualStyleBackColor = true; + buttonAdd.Click += ButtonAdd_Click; + // + // FormShops + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(541, 360); + Controls.Add(buttonUpd); + Controls.Add(buttonDel); + Controls.Add(buttonEdit); + Controls.Add(buttonAdd); + Controls.Add(dataGridView); + Name = "FormShops"; + StartPosition = FormStartPosition.CenterScreen; + Text = "Магазины"; + Load += FormShops_Load; + ((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); + ResumeLayout(false); + } + + #endregion + + private DataGridView dataGridView; + private Button buttonUpd; + private Button buttonDel; + private Button buttonEdit; + private Button buttonAdd; + } +} \ No newline at end of file diff --git a/FoodOrders/FoodOrdersView/FormShops.cs b/FoodOrders/FoodOrdersView/FormShops.cs new file mode 100644 index 0000000..9308cdd --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormShops.cs @@ -0,0 +1,104 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.BusinessLogicsContracts; +using Microsoft.Extensions.Logging; + +namespace FoodOrdersView +{ + public partial class FormShops : Form + { + private readonly ILogger _logger; + + private readonly IShopLogic _logic; + + public FormShops(ILogger logger, IShopLogic logic) + { + InitializeComponent(); + _logger = logger; + _logic = logic; + } + + private void FormShops_Load(object sender, EventArgs e) + { + LoadData(); + } + + private void LoadData() + { + try + { + var list = _logic.ReadList(null); + if (list != null) + { + dataGridView.DataSource = list; + dataGridView.Columns["Id"].Visible = false; + dataGridView.Columns["ShopName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + dataGridView.Columns["ShopDishs"].Visible = false; + } + _logger.LogInformation("Shops loading"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Shops loading error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonAdd_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormShop)); + if (service is FormShop form) + { + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } + + private void ButtonEdit_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 ButtonDel_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("Deletion of shop"); + try + { + if (!_logic.Delete(new ShopBindingModel { Id = id })) + { + throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Shop deletion error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } + + private void ButtonUpd_Click(object sender, EventArgs e) + { + LoadData(); + } + } +} diff --git a/FoodOrders/FoodOrdersView/FormShops.resx b/FoodOrders/FoodOrdersView/FormShops.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/FoodOrders/FoodOrdersView/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/FoodOrders/FoodOrdersView/Program.cs b/FoodOrders/FoodOrdersView/Program.cs index c668d54..f33a9dd 100644 --- a/FoodOrders/FoodOrdersView/Program.cs +++ b/FoodOrders/FoodOrdersView/Program.cs @@ -38,10 +38,12 @@ namespace FoodOrdersView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -50,6 +52,9 @@ namespace FoodOrdersView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file From 9b7f99f36adbce43f2784db2bc229198b9808f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9F=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D1=86=D0=B5=D0=B2?= Date: Mon, 25 Mar 2024 01:45:28 +0400 Subject: [PATCH 4/8] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs | 2 +- FoodOrders/FoodOrdersView/FormMakeShipment.cs | 4 ++-- FoodOrders/FoodOrdersView/FormShop.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs index 14c24f0..d018863 100644 --- a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs +++ b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs @@ -96,7 +96,7 @@ namespace FoodOrdersBusinessLogic.BusinessLogics } if (count <= 0) { - throw new ArgumentException("Количество товаров(мороженого) в магазине должно быть больше нуля", nameof(count)); + throw new ArgumentException("Количество товаров(блюд) в магазине должно быть больше нуля", nameof(count)); } _logger.LogInformation("MakeShipment(GetElement). ShopName: {ShopName}. Id: {Id}", shopModel.ShopName, shopModel.Id); var shop = _shopStorage.GetElement(shopModel); diff --git a/FoodOrders/FoodOrdersView/FormMakeShipment.cs b/FoodOrders/FoodOrdersView/FormMakeShipment.cs index 1134ff0..73244a0 100644 --- a/FoodOrders/FoodOrdersView/FormMakeShipment.cs +++ b/FoodOrders/FoodOrdersView/FormMakeShipment.cs @@ -22,7 +22,7 @@ namespace FoodOrdersView private void FormMakeShipment_Load(object sender, EventArgs e) { - _logger.LogInformation("Ice creams loading"); + _logger.LogInformation("Dishs loading"); try { var list = _logicDish.ReadList(null); @@ -36,7 +36,7 @@ namespace FoodOrdersView } catch (Exception ex) { - _logger.LogError(ex, "Ice creams loading error"); + _logger.LogError(ex, "Dishs loading error"); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } _logger.LogInformation("Shops loading"); diff --git a/FoodOrders/FoodOrdersView/FormShop.cs b/FoodOrders/FoodOrdersView/FormShop.cs index 0f61588..92934da 100644 --- a/FoodOrders/FoodOrdersView/FormShop.cs +++ b/FoodOrders/FoodOrdersView/FormShop.cs @@ -53,7 +53,7 @@ namespace FoodOrdersView private void LoadData() { - _logger.LogInformation("Shop ice creams loading"); + _logger.LogInformation("Shop dishs loading"); try { if (_shopDishs != null) @@ -67,7 +67,7 @@ namespace FoodOrdersView } catch (Exception ex) { - _logger.LogError(ex, "Shop ice creams loading error"); + _logger.LogError(ex, "Shop dishs loading error"); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } } From 238b04bf5c1922878ae904d171b71e5df0051ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9F=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D1=86=D0=B5=D0=B2?= Date: Mon, 15 Apr 2024 23:43:49 +0400 Subject: [PATCH 5/8] =?UTF-8?q?=D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=B0=D1=8F?= =?UTF-8?q?=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=202=20(=D1=83=D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D0=B0=D1=8F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{FoodLogic.cs => DishLogic.cs} | 0 .../BusinessLogics/OrderLogic.cs | 86 ++++++++++- .../BusinessLogics/ShopLogic.cs | 10 ++ .../BindingModels/ShopBindingModel.cs | 2 + .../BusinessLogicsContracts/IShopLogic.cs | 2 + .../StoragesContracts/IShopStorage.cs | 3 + .../ViewModels/ShopViewModel.cs | 3 + .../FoodOrdersDataModels/Models/IShopModel.cs | 2 + .../DataFileSingleton.cs | 6 + .../FoodOrdersFileImplement.csproj | 4 + .../Implements/ShopStorage.cs | 137 ++++++++++++++++++ .../FoodOrdersFileImplement/Models/Shop.cs | 116 +++++++++++++++ .../Implements/ShopStorage.cs | 6 + .../FoodOrdersListImplement/Models/Shop.cs | 2 + .../FoodOrdersView/FormDishSale.Designer.cs | 128 ++++++++++++++++ FoodOrders/FoodOrdersView/FormDishSale.cs | 87 +++++++++++ FoodOrders/FoodOrdersView/FormDishSale.resx | 120 +++++++++++++++ FoodOrders/FoodOrdersView/FormMain.cs | 9 ++ .../FoodOrdersView/FormMain.designer.cs | 17 ++- .../FoodOrdersView/FormShop.Designer.cs | 100 ++++++++----- FoodOrders/FoodOrdersView/FormShop.cs | 7 + FoodOrders/FoodOrdersView/Program.cs | 1 + 22 files changed, 805 insertions(+), 43 deletions(-) rename FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/{FoodLogic.cs => DishLogic.cs} (100%) create mode 100644 FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs create mode 100644 FoodOrders/FoodOrdersFileImplement/Models/Shop.cs create mode 100644 FoodOrders/FoodOrdersView/FormDishSale.Designer.cs create mode 100644 FoodOrders/FoodOrdersView/FormDishSale.cs create mode 100644 FoodOrders/FoodOrdersView/FormDishSale.resx diff --git a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/FoodLogic.cs b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/DishLogic.cs similarity index 100% rename from FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/FoodLogic.cs rename to FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/DishLogic.cs diff --git a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/OrderLogic.cs b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/OrderLogic.cs index b328bf2..b334e4a 100644 --- a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/OrderLogic.cs @@ -4,6 +4,7 @@ using FoodOrdersContracts.SearchModels; using FoodOrdersContracts.StoragesContracts; using FoodOrdersContracts.ViewModels; using FoodOrdersDataModels.Enums; +using FoodOrdersDataModels.Models; using Microsoft.Extensions.Logging; namespace FoodOrdersBusinessLogic.BusinessLogics @@ -14,10 +15,19 @@ namespace FoodOrdersBusinessLogic.BusinessLogics private readonly IOrderStorage _orderStorage; - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + private readonly IShopStorage _shopStorage; + + private readonly IShopLogic _shopLogic; + + private readonly IDishStorage _dishStorage; + + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IShopLogic shopLogic, IDishStorage dishStorage, IShopStorage shopStorage) { _logger = logger; _orderStorage = orderStorage; + _shopLogic = shopLogic; + _dishStorage = dishStorage; + _shopStorage = shopStorage; } public bool CreateOrder(OrderBindingModel model) @@ -90,7 +100,67 @@ namespace FoodOrdersBusinessLogic.BusinessLogics _logger.LogInformation("Order. Id: {Id}. Sum: {Sum}. DishId: {DishId}. DishCount: {Count}", model.Id, model.Sum, model.DishId, model.Count); } + public bool CheckThenMakeShipment(IDishModel dish, int count) + { + if (count <= 0) + { + _logger.LogWarning("Check then make shipment operation error. Dish count < 0."); + return false; + } + int freeSpace = 0; + foreach (var shop in _shopStorage.GetFullList()) + { + freeSpace += shop.MaxCountDishs; + foreach (var c in shop.ShopDishs) + { + freeSpace -= c.Value.Item2; + } + } + + if (freeSpace < count) + { + _logger.LogWarning("Check then supply operation error. There's no place for new dishs in shops."); + return false; + } + + foreach (var shop in _shopStorage.GetFullList()) + { + freeSpace = shop.MaxCountDishs; + + foreach (var c in shop.ShopDishs) + freeSpace -= c.Value.Item2; + + if (freeSpace <= 0) + continue; + + if (freeSpace >= count) + { + if (_shopLogic.MakeShipment(new ShopSearchModel() { Id = shop.Id }, dish, count)) + count = 0; + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + if (freeSpace < count) + { + if (_shopLogic.MakeShipment(new ShopSearchModel() { Id = shop.Id }, dish, freeSpace)) + count -= freeSpace; + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + if (count <= 0) + { + return true; + } + } + return false; + } private bool ChangeStatus(OrderBindingModel model, OrderStatus newStatus) { CheckModel(model, false); @@ -106,6 +176,20 @@ namespace FoodOrdersBusinessLogic.BusinessLogics newStatus, order.Status); return false; } + if (newStatus == OrderStatus.Выдан) + { + var dish = _dishStorage.GetElement(new DishSearchModel() { Id = order.DishId }); + if (dish == null) + { + _logger.LogWarning("Change status operation failed. Dish not found"); + return false; + } + if (!CheckThenMakeShipment(dish, order.Count)) + { + _logger.LogWarning("Change status operation failed. Dishs delivery operation failed"); + return false; + } + } model.DishId = order.DishId; model.Count = order.Count; model.Sum = order.Sum; diff --git a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs index d018863..784b94f 100644 --- a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs +++ b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ShopLogic.cs @@ -105,6 +105,11 @@ namespace FoodOrdersBusinessLogic.BusinessLogics _logger.LogWarning("MakeShipment(GetElement). Element not found"); return false; } + if (shop.MaxCountDishs - shop.ShopDishs.Sum(x => x.Value.Item2) < count) + { + _logger.LogWarning("MakeShipment error. No space for new dishs"); + return false; + } if (shop.ShopDishs.ContainsKey(dish.Id)) { var shopIC = shop.ShopDishs[dish.Id]; @@ -124,6 +129,7 @@ namespace FoodOrdersBusinessLogic.BusinessLogics Id = shop.Id, ShopName = shop.ShopName, Address = shop.Address, + MaxCountDishs = shop.MaxCountDishs, DateOpening = shop.DateOpening, ShopDishs = shop.ShopDishs, }) == null) @@ -162,5 +168,9 @@ namespace FoodOrdersBusinessLogic.BusinessLogics throw new InvalidOperationException("Магазин с таким названием уже есть"); } } + public bool SellDish(IDishModel dish, int count) + { + return _shopStorage.SellDish(dish, count); + } } } diff --git a/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs b/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs index cc31939..9ab8a11 100644 --- a/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs +++ b/FoodOrders/FoodOrdersContracts/BindingModels/ShopBindingModel.cs @@ -10,6 +10,8 @@ namespace FoodOrdersContracts.BindingModels public string Address { get; set; } = string.Empty; + public int MaxCountDishs { get; set; } + public DateTime DateOpening { get; set; } = DateTime.Now; public Dictionary ShopDishs diff --git a/FoodOrders/FoodOrdersContracts/BusinessLogicsContracts/IShopLogic.cs b/FoodOrders/FoodOrdersContracts/BusinessLogicsContracts/IShopLogic.cs index e405f1b..5b8d0dd 100644 --- a/FoodOrders/FoodOrdersContracts/BusinessLogicsContracts/IShopLogic.cs +++ b/FoodOrders/FoodOrdersContracts/BusinessLogicsContracts/IShopLogic.cs @@ -18,5 +18,7 @@ namespace FoodOrdersContracts.BusinessLogicsContracts bool Delete(ShopBindingModel model); bool MakeShipment(ShopSearchModel shopModel, IDishModel dish, int count); + + bool SellDish(IDishModel dish, int count); } } diff --git a/FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs b/FoodOrders/FoodOrdersContracts/StoragesContracts/IShopStorage.cs index affa849..6d4327b 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 { @@ -17,5 +18,7 @@ namespace FoodOrdersContracts.StoragesContracts ShopViewModel? Update(ShopBindingModel model); ShopViewModel? Delete(ShopBindingModel model); + + bool SellDish(IDishModel model, int count); } } diff --git a/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs b/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs index 22e3f12..158dff2 100644 --- a/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs +++ b/FoodOrders/FoodOrdersContracts/ViewModels/ShopViewModel.cs @@ -13,6 +13,9 @@ namespace FoodOrdersContracts.ViewModels [DisplayName("Адрес")] public string Address { get; set; } = string.Empty; + [DisplayName("Максимум блюд")] + public int MaxCountDishs { get; set; } + [DisplayName("Дата открытия")] public DateTime DateOpening { get; set; } = DateTime.Now; diff --git a/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs b/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs index 3a65e5b..93b0d1e 100644 --- a/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs +++ b/FoodOrders/FoodOrdersDataModels/Models/IShopModel.cs @@ -6,6 +6,8 @@ string Address { get; } + int MaxCountDishs { get; } + DateTime DateOpening { get; } Dictionary ShopDishs { get; } diff --git a/FoodOrders/FoodOrdersFileImplement/DataFileSingleton.cs b/FoodOrders/FoodOrdersFileImplement/DataFileSingleton.cs index e2c4e42..bf9ed14 100644 --- a/FoodOrders/FoodOrdersFileImplement/DataFileSingleton.cs +++ b/FoodOrders/FoodOrdersFileImplement/DataFileSingleton.cs @@ -13,12 +13,15 @@ namespace FoodOrdersFileImplement 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 Dishs { get; private set; } + public List Shops { get; private set; } + public static DataFileSingleton GetInstance() { if (instance == null) @@ -34,11 +37,14 @@ namespace FoodOrdersFileImplement 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)!)!; Dishs = 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/FoodOrdersFileImplement.csproj b/FoodOrders/FoodOrdersFileImplement/FoodOrdersFileImplement.csproj index 51e14c2..61aa7a8 100644 --- a/FoodOrders/FoodOrdersFileImplement/FoodOrdersFileImplement.csproj +++ b/FoodOrders/FoodOrdersFileImplement/FoodOrdersFileImplement.csproj @@ -6,6 +6,10 @@ enable + + + + diff --git a/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs b/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..a5f1a52 --- /dev/null +++ b/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs @@ -0,0 +1,137 @@ +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? GetElement(ShopSearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + return source.Shops.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel; + } + + public List GetFilteredList(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName)) + { + return new(); + } + return source.Shops + .Select(x => x.GetViewModel) + .Where(x => x.ShopName.Contains(model.ShopName ?? string.Empty)) + .ToList(); + } + + public List GetFullList() + { + return source.Shops.Select(shop => shop.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 ShopViewModel? Delete(ShopBindingModel model) + { + var shop = source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (shop == null) + { + return null; + } + source.Shops.Remove(shop); + source.SaveShops(); + return shop.GetViewModel; + } + + public bool SellDish(IDishModel model, int count) + { + var dish = source.Dishs.FirstOrDefault(x => x.Id == model.Id); + + if (dish == null) + { + return false; + } + + + var shopDishs = source.Shops.SelectMany(shop => shop.ShopDishs.Where(c => c.Value.Item1.Id == dish.Id)); + + int countStore = 0; + + foreach (var it in shopDishs) + countStore += it.Value.Item2; + + if (count > countStore) + return false; + + foreach (var shop in source.Shops) + { + var dishs = shop.ShopDishs; + + foreach (var c in dishs.Where(x => x.Value.Item1.Id == dish.Id)) + { + int min = Math.Min(c.Value.Item2, count); + dishs[c.Value.Item1.Id] = (c.Value.Item1, c.Value.Item2 - min); + count -= min; + + if (count <= 0) + break; + } + + shop.Update(new ShopBindingModel + { + Id = shop.Id, + ShopName = shop.ShopName, + Address = shop.Address, + MaxCountDishs = shop.MaxCountDishs, + DateOpening = shop.DateOpening, + ShopDishs = dishs + }); + + source.SaveShops(); + + if (count <= 0) + return true; + } + + return true; + } + } +} diff --git a/FoodOrders/FoodOrdersFileImplement/Models/Shop.cs b/FoodOrders/FoodOrdersFileImplement/Models/Shop.cs new file mode 100644 index 0000000..33d1219 --- /dev/null +++ b/FoodOrders/FoodOrdersFileImplement/Models/Shop.cs @@ -0,0 +1,116 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.ViewModels; +using FoodOrdersDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace FoodOrdersFileImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + public string ShopName { get; private set; } = string.Empty; + public string Address { get; private set; } = string.Empty; + public int MaxCountDishs { get; private set; } + public DateTime DateOpening { get; private set; } + public Dictionary Dishs { get; private set; } = new(); + private Dictionary? _shopDishs = null; + + public Dictionary ShopDishs + { + get + { + if (_shopDishs == null) + { + var source = DataFileSingleton.GetInstance(); + _shopDishs = Dishs.ToDictionary( + x => x.Key, + y => ((source.Dishs.FirstOrDefault(z => z.Id == y.Key) as IDishModel)!, y.Value) + ); + } + return _shopDishs; + } + } + + public static Shop? Create(ShopBindingModel? model) + { + if (model == null) + { + return null; + } + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + MaxCountDishs = model.MaxCountDishs, + DateOpening = model.DateOpening, + Dishs = model.ShopDishs.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, + MaxCountDishs = Convert.ToInt32(element.Element("MaxCountDishs")!.Value), + DateOpening = Convert.ToDateTime(element.Element("DateOpening")!.Value), + Dishs = element.Element("ShopDishs")!.Elements("ShopDish").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; + MaxCountDishs = model.MaxCountDishs; + DateOpening = model.DateOpening; + if (model.ShopDishs.Count > 0) + { + Dishs = model.ShopDishs.ToDictionary(x => x.Key, x => x.Value.Item2); + _shopDishs = null; + } + } + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + MaxCountDishs = MaxCountDishs, + DateOpening = DateOpening, + ShopDishs = ShopDishs, + }; + + public XElement GetXElement => new( + "Shop", + new XAttribute("Id", Id), + new XElement("ShopName", ShopName), + new XElement("Address", Address), + new XElement("MaxCountDishs", MaxCountDishs), + new XElement("DateOpening", DateOpening.ToString()), + new XElement("ShopDishs", Dishs.Select(x => + new XElement("ShopDish", + new XElement("Key", x.Key), + new XElement("Value", x.Value))) + .ToArray())); + } +} diff --git a/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs b/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs index bdf6d75..094735f 100644 --- a/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs +++ b/FoodOrders/FoodOrdersListImplement/Implements/ShopStorage.cs @@ -2,12 +2,18 @@ using FoodOrdersContracts.SearchModels; using FoodOrdersContracts.StoragesContracts; using FoodOrdersContracts.ViewModels; +using FoodOrdersDataModels.Models; using FoodOrdersListImplement.Models; namespace FoodOrdersListImplement.Implements { public class ShopStorage : IShopStorage { + public bool SellDish(IDishModel dish, int count) + { + throw new NotImplementedException(); + } + private readonly DataListSingleton _source; public ShopStorage() diff --git a/FoodOrders/FoodOrdersListImplement/Models/Shop.cs b/FoodOrders/FoodOrdersListImplement/Models/Shop.cs index 8d9b1e9..1dce43b 100644 --- a/FoodOrders/FoodOrdersListImplement/Models/Shop.cs +++ b/FoodOrders/FoodOrdersListImplement/Models/Shop.cs @@ -12,6 +12,8 @@ namespace FoodOrdersListImplement.Models public string Address { get; private set; } = string.Empty; + public int MaxCountDishs { get; private set; } + public DateTime DateOpening { get; private set; } public Dictionary ShopDishs diff --git a/FoodOrders/FoodOrdersView/FormDishSale.Designer.cs b/FoodOrders/FoodOrdersView/FormDishSale.Designer.cs new file mode 100644 index 0000000..ac0d746 --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormDishSale.Designer.cs @@ -0,0 +1,128 @@ +namespace FoodOrdersView +{ + partial class FormDishSale + { + /// + /// 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(); + buttonSale = new Button(); + textBoxCount = new TextBox(); + labelCount = new Label(); + comboBoxDish = new ComboBox(); + labelDish = new Label(); + SuspendLayout(); + // + // buttonCancel + // + buttonCancel.Location = new Point(289, 111); + buttonCancel.Margin = new Padding(5, 4, 5, 4); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(101, 36); + buttonCancel.TabIndex = 17; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += ButtonCancel_Click; + // + // buttonSale + // + buttonSale.Location = new Point(182, 111); + buttonSale.Margin = new Padding(5, 4, 5, 4); + buttonSale.Name = "buttonSale"; + buttonSale.Size = new Size(101, 36); + buttonSale.TabIndex = 16; + buttonSale.Text = "Продать"; + buttonSale.UseVisualStyleBackColor = true; + buttonSale.Click += ButtonSale_Click; + // + // textBoxCount + // + textBoxCount.Location = new Point(115, 68); + textBoxCount.Margin = new Padding(5, 4, 5, 4); + textBoxCount.Name = "textBoxCount"; + textBoxCount.Size = new Size(287, 27); + textBoxCount.TabIndex = 15; + // + // labelCount + // + labelCount.AutoSize = true; + labelCount.Location = new Point(15, 72); + labelCount.Margin = new Padding(5, 0, 5, 0); + labelCount.Name = "labelCount"; + labelCount.Size = new Size(97, 20); + labelCount.TabIndex = 14; + labelCount.Text = "Количество :"; + // + // comboBoxDish + // + comboBoxDish.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxDish.FormattingEnabled = true; + comboBoxDish.Location = new Point(115, 20); + comboBoxDish.Margin = new Padding(5, 4, 5, 4); + comboBoxDish.Name = "comboBoxDish"; + comboBoxDish.Size = new Size(287, 28); + comboBoxDish.TabIndex = 13; + // + // labelDish + // + labelDish.AutoSize = true; + labelDish.Location = new Point(15, 23); + labelDish.Margin = new Padding(5, 0, 5, 0); + labelDish.Name = "labelDish"; + labelDish.Size = new Size(62, 20); + labelDish.TabIndex = 12; + labelDish.Text = "Блюдо :"; + // + // FormDishSale + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(426, 164); + Controls.Add(buttonCancel); + Controls.Add(buttonSale); + Controls.Add(textBoxCount); + Controls.Add(labelCount); + Controls.Add(comboBoxDish); + Controls.Add(labelDish); + Margin = new Padding(3, 4, 3, 4); + Name = "FormDishSale"; + StartPosition = FormStartPosition.CenterScreen; + Text = "Продажа блюд"; + Load += FormDishSale_Load; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Button buttonCancel; + private Button buttonSale; + private TextBox textBoxCount; + private Label labelCount; + private ComboBox comboBoxDish; + private Label labelDish; + } +} \ No newline at end of file diff --git a/FoodOrders/FoodOrdersView/FormDishSale.cs b/FoodOrders/FoodOrdersView/FormDishSale.cs new file mode 100644 index 0000000..c3cb5c4 --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormDishSale.cs @@ -0,0 +1,87 @@ +using FoodOrdersContracts.BusinessLogicsContracts; +using FoodOrdersContracts.BindingModels; +using Microsoft.Extensions.Logging; + +namespace FoodOrdersView +{ + public partial class FormDishSale : Form + { + private readonly ILogger _logger; + + private readonly IDishLogic _logicDish; + + private readonly IShopLogic _logicShop; + + public FormDishSale(ILogger logger, IDishLogic logicDish, IShopLogic logicShop) + { + InitializeComponent(); + _logger = logger; + _logicDish = logicDish; + _logicShop = logicShop; + } + + private void FormDishSale_Load(object sender, EventArgs e) + { + _logger.LogInformation("Dishs loading"); + try + { + var list = _logicDish.ReadList(null); + if (list != null) + { + comboBoxDish.DisplayMember = "DishName"; + comboBoxDish.ValueMember = "Id"; + comboBoxDish.DataSource = list; + comboBoxDish.SelectedItem = null; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Dishs loading error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonSale_Click(object sender, EventArgs e) + { + if (comboBoxDish.SelectedValue == null) + { + MessageBox.Show("Выберите блюдо", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (string.IsNullOrEmpty(textBoxCount.Text)) + { + MessageBox.Show("Заполните поле Количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("Dish sale"); + try + { + var operationResult = _logicShop.SellDish( + new DishBindingModel + { + Id = Convert.ToInt32(comboBoxDish.SelectedValue) + }, + 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, "Dish sale error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/FoodOrders/FoodOrdersView/FormDishSale.resx b/FoodOrders/FoodOrdersView/FormDishSale.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/FoodOrders/FoodOrdersView/FormDishSale.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/FoodOrders/FoodOrdersView/FormMain.cs b/FoodOrders/FoodOrdersView/FormMain.cs index 7f53cc2..c20982d 100644 --- a/FoodOrders/FoodOrdersView/FormMain.cs +++ b/FoodOrders/FoodOrdersView/FormMain.cs @@ -162,5 +162,14 @@ namespace FoodOrdersView form.ShowDialog(); } } + + private void продажаБлюдToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormDishSale)); + if (service is FormDishSale form) + { + form.ShowDialog(); + } + } } } \ No newline at end of file diff --git a/FoodOrders/FoodOrdersView/FormMain.designer.cs b/FoodOrders/FoodOrdersView/FormMain.designer.cs index 15f6287..6537ab2 100644 --- a/FoodOrders/FoodOrdersView/FormMain.designer.cs +++ b/FoodOrders/FoodOrdersView/FormMain.designer.cs @@ -40,6 +40,7 @@ buttonCreateOrder = new Button(); dataGridView = new DataGridView(); buttonUpd = new Button(); + продажаБлюдToolStripMenuItem = new ToolStripMenuItem(); menuStrip.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); SuspendLayout(); @@ -47,7 +48,7 @@ // menuStrip // menuStrip.ImageScalingSize = new Size(20, 20); - menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, пополнениеМагазинаToolStripMenuItem }); + menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, пополнениеМагазинаToolStripMenuItem, продажаБлюдToolStripMenuItem }); menuStrip.Location = new Point(0, 0); menuStrip.Name = "menuStrip"; menuStrip.Padding = new Padding(8, 3, 0, 3); @@ -65,21 +66,21 @@ // компонентыToolStripMenuItem // компонентыToolStripMenuItem.Name = "компонентыToolStripMenuItem"; - компонентыToolStripMenuItem.Size = new Size(224, 26); + компонентыToolStripMenuItem.Size = new Size(182, 26); компонентыToolStripMenuItem.Text = "Компоненты"; компонентыToolStripMenuItem.Click += КомпонентыToolStripMenuItem_Click; // // блюдоToolStripMenuItem // блюдоToolStripMenuItem.Name = "блюдоToolStripMenuItem"; - блюдоToolStripMenuItem.Size = new Size(224, 26); + блюдоToolStripMenuItem.Size = new Size(182, 26); блюдоToolStripMenuItem.Text = "Еда"; блюдоToolStripMenuItem.Click += БлюдоToolStripMenuItem_Click; // // магазиныToolStripMenuItem // магазиныToolStripMenuItem.Name = "магазиныToolStripMenuItem"; - магазиныToolStripMenuItem.Size = new Size(224, 26); + магазиныToolStripMenuItem.Size = new Size(182, 26); магазиныToolStripMenuItem.Text = "Магазины"; магазиныToolStripMenuItem.Click += магазиныToolStripMenuItem_Click; // @@ -168,6 +169,13 @@ buttonUpd.UseVisualStyleBackColor = true; buttonUpd.Click += ButtonUpd_Click; // + // продажаБлюдToolStripMenuItem + // + продажаБлюдToolStripMenuItem.Name = "продажаБлюдToolStripMenuItem"; + продажаБлюдToolStripMenuItem.Size = new Size(128, 24); + продажаБлюдToolStripMenuItem.Text = "Продажа блюд"; + продажаБлюдToolStripMenuItem.Click += продажаБлюдToolStripMenuItem_Click; + // // FormMain // AutoScaleDimensions = new SizeF(8F, 20F); @@ -207,6 +215,7 @@ private Button buttonUpd; private ToolStripMenuItem магазиныToolStripMenuItem; private ToolStripMenuItem пополнениеМагазинаToolStripMenuItem; + private ToolStripMenuItem продажаБлюдToolStripMenuItem; } } diff --git a/FoodOrders/FoodOrdersView/FormShop.Designer.cs b/FoodOrders/FoodOrdersView/FormShop.Designer.cs index f844a1b..52861a9 100644 --- a/FoodOrders/FoodOrdersView/FormShop.Designer.cs +++ b/FoodOrders/FoodOrdersView/FormShop.Designer.cs @@ -33,14 +33,16 @@ labelAddress = new Label(); textBoxAddress = new TextBox(); dateTimePicker = new DateTimePicker(); - labelOpeningDate = new Label(); + labelDateOpening = new Label(); groupBoxDishs = new GroupBox(); dataGridView = new DataGridView(); - buttonSave = new Button(); - buttonCancel = new Button(); ColumnId = new DataGridViewTextBoxColumn(); ColumnName = new DataGridViewTextBoxColumn(); ColumnCount = new DataGridViewTextBoxColumn(); + buttonSave = new Button(); + buttonCancel = new Button(); + textBoxMaximum = new TextBox(); + labelMaximum = new Label(); groupBoxDishs.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); SuspendLayout(); @@ -89,24 +91,24 @@ dateTimePicker.Size = new Size(249, 27); dateTimePicker.TabIndex = 5; // - // labelOpeningDate + // labelDateOpening // - labelOpeningDate.AutoSize = true; - labelOpeningDate.Location = new Point(16, 92); - labelOpeningDate.Margin = new Padding(5, 0, 5, 0); - labelOpeningDate.Name = "labelOpeningDate"; - labelOpeningDate.Size = new Size(117, 20); - labelOpeningDate.TabIndex = 6; - labelOpeningDate.Text = "Дата открытия :"; + labelDateOpening.AutoSize = true; + labelDateOpening.Location = new Point(16, 92); + labelDateOpening.Margin = new Padding(5, 0, 5, 0); + labelDateOpening.Name = "labelDateOpening"; + labelDateOpening.Size = new Size(117, 20); + labelDateOpening.TabIndex = 6; + labelDateOpening.Text = "Дата открытия :"; // // groupBoxDishs // groupBoxDishs.Controls.Add(dataGridView); - groupBoxDishs.Location = new Point(5, 133); + groupBoxDishs.Location = new Point(5, 184); groupBoxDishs.Margin = new Padding(5, 4, 5, 4); groupBoxDishs.Name = "groupBoxDishs"; groupBoxDishs.Padding = new Padding(5, 4, 5, 4); - groupBoxDishs.Size = new Size(536, 384); + groupBoxDishs.Size = new Size(536, 333); groupBoxDishs.TabIndex = 7; groupBoxDishs.TabStop = false; groupBoxDishs.Text = "Блюдо"; @@ -127,31 +129,9 @@ dataGridView.RowHeadersVisible = false; dataGridView.RowHeadersWidth = 51; dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; - dataGridView.Size = new Size(522, 356); + dataGridView.Size = new Size(522, 305); dataGridView.TabIndex = 0; // - // buttonSave - // - buttonSave.Location = new Point(291, 525); - buttonSave.Margin = new Padding(5, 4, 5, 4); - buttonSave.Name = "buttonSave"; - buttonSave.Size = new Size(101, 36); - buttonSave.TabIndex = 8; - buttonSave.Text = "Сохранить"; - buttonSave.UseVisualStyleBackColor = true; - buttonSave.Click += ButtonSave_Click; - // - // buttonCancel - // - buttonCancel.Location = new Point(410, 525); - buttonCancel.Margin = new Padding(5, 4, 5, 4); - buttonCancel.Name = "buttonCancel"; - buttonCancel.Size = new Size(101, 36); - buttonCancel.TabIndex = 9; - buttonCancel.Text = "Отмена"; - buttonCancel.UseVisualStyleBackColor = true; - buttonCancel.Click += ButtonCancel_Click; - // // ColumnId // ColumnId.HeaderText = "Id"; @@ -177,15 +157,57 @@ ColumnCount.ReadOnly = true; ColumnCount.Width = 125; // + // buttonSave + // + buttonSave.Location = new Point(291, 525); + buttonSave.Margin = new Padding(5, 4, 5, 4); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(101, 36); + buttonSave.TabIndex = 8; + buttonSave.Text = "Сохранить"; + buttonSave.UseVisualStyleBackColor = true; + buttonSave.Click += ButtonSave_Click; + // + // buttonCancel + // + buttonCancel.Location = new Point(410, 525); + buttonCancel.Margin = new Padding(5, 4, 5, 4); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(101, 36); + buttonCancel.TabIndex = 9; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += ButtonCancel_Click; + // + // textBoxMaximum + // + textBoxMaximum.Location = new Point(193, 133); + textBoxMaximum.Margin = new Padding(5, 4, 5, 4); + textBoxMaximum.Name = "textBoxMaximum"; + textBoxMaximum.Size = new Size(199, 27); + textBoxMaximum.TabIndex = 13; + // + // labelMaximum + // + labelMaximum.AutoSize = true; + labelMaximum.Location = new Point(16, 137); + labelMaximum.Margin = new Padding(5, 0, 5, 0); + labelMaximum.Name = "labelMaximum"; + labelMaximum.Size = new Size(130, 20); + labelMaximum.TabIndex = 12; + labelMaximum.Text = "Максимум блюд :"; + // // FormShop // AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(546, 576); + Controls.Add(textBoxMaximum); + Controls.Add(labelMaximum); Controls.Add(buttonCancel); Controls.Add(buttonSave); Controls.Add(groupBoxDishs); - Controls.Add(labelOpeningDate); + Controls.Add(labelDateOpening); Controls.Add(dateTimePicker); Controls.Add(textBoxAddress); Controls.Add(labelAddress); @@ -209,7 +231,7 @@ private Label labelAddress; private TextBox textBoxAddress; private DateTimePicker dateTimePicker; - private Label labelOpeningDate; + private Label labelDateOpening; private GroupBox groupBoxDishs; private DataGridView dataGridView; private Button buttonSave; @@ -217,5 +239,7 @@ private DataGridViewTextBoxColumn ColumnId; private DataGridViewTextBoxColumn ColumnName; private DataGridViewTextBoxColumn ColumnCount; + private TextBox textBoxMaximum; + private Label labelMaximum; } } \ No newline at end of file diff --git a/FoodOrders/FoodOrdersView/FormShop.cs b/FoodOrders/FoodOrdersView/FormShop.cs index 92934da..027db01 100644 --- a/FoodOrders/FoodOrdersView/FormShop.cs +++ b/FoodOrders/FoodOrdersView/FormShop.cs @@ -39,6 +39,7 @@ namespace FoodOrdersView textBoxName.Text = view.ShopName; textBoxAddress.Text = view.Address; dateTimePicker.Value = view.DateOpening; + textBoxMaximum.Text = view.MaxCountDishs.ToString(); _shopDishs = view.ShopDishs ?? new Dictionary(); LoadData(); } @@ -89,6 +90,11 @@ namespace FoodOrdersView MessageBox.Show("Заполните дату", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } + if (string.IsNullOrEmpty(textBoxMaximum.Text)) + { + MessageBox.Show("Заполните максимальное количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } _logger.LogInformation("Shop saving"); try { @@ -98,6 +104,7 @@ namespace FoodOrdersView ShopName = textBoxName.Text, Address = textBoxAddress.Text, DateOpening = dateTimePicker.Value, + MaxCountDishs = Convert.ToInt32(textBoxMaximum.Text), ShopDishs = _shopDishs }; var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model); diff --git a/FoodOrders/FoodOrdersView/Program.cs b/FoodOrders/FoodOrdersView/Program.cs index 2690dc0..39088e2 100644 --- a/FoodOrders/FoodOrdersView/Program.cs +++ b/FoodOrders/FoodOrdersView/Program.cs @@ -55,6 +55,7 @@ namespace FoodOrdersView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file From 21178474da69cbfc26521ce61e136a75de0e2032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9F=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D1=86=D0=B5=D0=B2?= Date: Tue, 16 Apr 2024 21:01:35 +0400 Subject: [PATCH 6/8] =?UTF-8?q?=D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=B0=D1=8F?= =?UTF-8?q?=203=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=BD=D0=B0=D1=8F=20(=D1=83=D1=81=D0=BB=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D0=B0=D1=8F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FoodOrdersDatabase.cs | 4 +- .../Implemets/ShopStorage.cs | 146 ++++++++++ .../20240416140734_Hard.Designer.cs | 250 ++++++++++++++++++ .../Migrations/20240416140734_Hard.cs | 78 ++++++ .../FoodOrdersDatabaseModelSnapshot.cs | 79 ++++++ .../Models/Dish.cs | 2 + .../Models/Shop.cs | 110 ++++++++ .../Models/ShopDish.cs | 22 ++ 8 files changed, 690 insertions(+), 1 deletion(-) create mode 100644 FoodOrders/FoodOrdersDatabaseImplement/Implemets/ShopStorage.cs create mode 100644 FoodOrders/FoodOrdersDatabaseImplement/Migrations/20240416140734_Hard.Designer.cs create mode 100644 FoodOrders/FoodOrdersDatabaseImplement/Migrations/20240416140734_Hard.cs create mode 100644 FoodOrders/FoodOrdersDatabaseImplement/Models/Shop.cs create mode 100644 FoodOrders/FoodOrdersDatabaseImplement/Models/ShopDish.cs diff --git a/FoodOrders/FoodOrdersDatabaseImplement/FoodOrdersDatabase.cs b/FoodOrders/FoodOrdersDatabaseImplement/FoodOrdersDatabase.cs index 6d47ff1..a7227af 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/FoodOrdersDatabase.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/FoodOrdersDatabase.cs @@ -15,7 +15,7 @@ optionsBuilder) { if (optionsBuilder.IsConfigured == false) { - optionsBuilder.UseSqlServer(@"Data Source=.\SQLEXPRESS;Initial Catalog=FoodOrdersDatabaseFull;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + optionsBuilder.UseSqlServer(@"Data Source=.\SQLEXPRESS;Initial Catalog=FoodOrdersDatabaseHard;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); } base.OnConfiguring(optionsBuilder); } @@ -23,5 +23,7 @@ optionsBuilder) public virtual DbSet Dishs { set; get; } public virtual DbSet DishComponents { set; get; } public virtual DbSet Orders { set; get; } + public virtual DbSet Shops { set; get; } + public virtual DbSet ShopDishs { set; get; } } } diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Implemets/ShopStorage.cs b/FoodOrders/FoodOrdersDatabaseImplement/Implemets/ShopStorage.cs new file mode 100644 index 0000000..fa8e224 --- /dev/null +++ b/FoodOrders/FoodOrdersDatabaseImplement/Implemets/ShopStorage.cs @@ -0,0 +1,146 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.SearchModels; +using FoodOrdersContracts.StoragesContracts; +using FoodOrdersContracts.ViewModels; +using FoodOrdersDatabaseImplement.Models; +using FoodOrdersDataModels.Models; +using Microsoft.EntityFrameworkCore; + +namespace FoodOrdersDatabaseImplement.Implements +{ + public class ShopStorage : IShopStorage + { + public List GetFullList() + { + using var context = new FoodOrdersDatabase(); + return context.Shops + .Include(x => x.Dishs) + .ThenInclude(x => x.Dish) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName)) + { + return new(); + } + using var context = new FoodOrdersDatabase(); + return context.Shops + .Include(x => x.Dishs) + .ThenInclude(x => x.Dish) + .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 FoodOrdersDatabase(); + return context.Shops + .Include(x => x.Dishs) + .ThenInclude(x => x.Dish) + .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 FoodOrdersDatabase(); + 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 FoodOrdersDatabase(); + 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.UpdateDishs(context, model); + transaction.Commit(); + return shop.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + using var context = new FoodOrdersDatabase(); + var element = context.Shops + .Include(x => x.Dishs) + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Shops.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + public bool SellDish(IDishModel model, int count) + { + using var context = new FoodOrdersDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + foreach (var shop in context.Shops.Include(x => x.Dishs).ThenInclude(x => x.Dish) + .Where(x => x.Dishs.Any(x => x.DishId == model.Id)) + .ToList()) + { + var iceCream = shop.ShopDishs[model.Id]; + int min = Math.Min(iceCream.Item2, count); + if (min == iceCream.Item2) + { + shop.ShopDishs.Remove(model.Id); + } + else + { + shop.ShopDishs[model.Id] = (iceCream.Item1, iceCream.Item2 - min); + } + shop.UpdateDishs(context, new() { Id = shop.Id, ShopDishs = shop.ShopDishs }); + count -= min; + if (count == 0) + { + context.SaveChanges(); + transaction.Commit(); + return true; + } + } + transaction.Rollback(); + return false; + } + catch + { + transaction.Rollback(); + throw; + } + } + } +} diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20240416140734_Hard.Designer.cs b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20240416140734_Hard.Designer.cs new file mode 100644 index 0000000..a10ee2e --- /dev/null +++ b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20240416140734_Hard.Designer.cs @@ -0,0 +1,250 @@ +// +using System; +using FoodOrdersDatabaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace FoodOrdersDatabaseImplement.Migrations +{ + [DbContext(typeof(FoodOrdersDatabase))] + [Migration("20240416140734_Hard")] + partial class Hard + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.16") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Cost") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Dish", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DishName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Dishs"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.DishComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentId") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DishId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ComponentId"); + + b.HasIndex("DishId"); + + b.ToTable("DishComponents"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DateCreate") + .HasColumnType("datetime2"); + + b.Property("DateImplement") + .HasColumnType("datetime2"); + + b.Property("DishId") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Sum") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("DishId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.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("MaxCountDishs") + .HasColumnType("int"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.ShopDish", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DishId") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("DishId"); + + b.HasIndex("ShopId"); + + b.ToTable("ShopDishs"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.DishComponent", b => + { + b.HasOne("FoodOrdersDatabaseImplement.Models.Component", "Component") + .WithMany("DishComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("FoodOrdersDatabaseImplement.Models.Dish", "Dish") + .WithMany("Components") + .HasForeignKey("DishId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Component"); + + b.Navigation("Dish"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Order", b => + { + b.HasOne("FoodOrdersDatabaseImplement.Models.Dish", "Dish") + .WithMany("Orders") + .HasForeignKey("DishId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Dish"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.ShopDish", b => + { + b.HasOne("FoodOrdersDatabaseImplement.Models.Dish", "Dish") + .WithMany("ShopDishs") + .HasForeignKey("DishId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("FoodOrdersDatabaseImplement.Models.Shop", "Shop") + .WithMany("Dishs") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Dish"); + + b.Navigation("Shop"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Component", b => + { + b.Navigation("DishComponents"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Dish", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + + b.Navigation("ShopDishs"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Shop", b => + { + b.Navigation("Dishs"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20240416140734_Hard.cs b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20240416140734_Hard.cs new file mode 100644 index 0000000..326bcfe --- /dev/null +++ b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20240416140734_Hard.cs @@ -0,0 +1,78 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace FoodOrdersDatabaseImplement.Migrations +{ + /// + public partial class Hard : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Shops", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ShopName = table.Column(type: "nvarchar(max)", nullable: false), + Address = table.Column(type: "nvarchar(max)", nullable: false), + DateOpening = table.Column(type: "datetime2", nullable: false), + MaxCountDishs = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Shops", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ShopDishs", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ShopId = table.Column(type: "int", nullable: false), + DishId = table.Column(type: "int", nullable: false), + Count = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ShopDishs", x => x.Id); + table.ForeignKey( + name: "FK_ShopDishs_Dishs_DishId", + column: x => x.DishId, + principalTable: "Dishs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ShopDishs_Shops_ShopId", + column: x => x.ShopId, + principalTable: "Shops", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ShopDishs_DishId", + table: "ShopDishs", + column: "DishId"); + + migrationBuilder.CreateIndex( + name: "IX_ShopDishs_ShopId", + table: "ShopDishs", + column: "ShopId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ShopDishs"); + + migrationBuilder.DropTable( + name: "Shops"); + } + } +} diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/FoodOrdersDatabaseModelSnapshot.cs b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/FoodOrdersDatabaseModelSnapshot.cs index ef235de..9aa17fb 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/FoodOrdersDatabaseModelSnapshot.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/FoodOrdersDatabaseModelSnapshot.cs @@ -121,6 +121,59 @@ namespace FoodOrdersDatabaseImplement.Migrations b.ToTable("Orders"); }); + modelBuilder.Entity("FoodOrdersDatabaseImplement.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("MaxCountDishs") + .HasColumnType("int"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.ShopDish", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DishId") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("DishId"); + + b.HasIndex("ShopId"); + + b.ToTable("ShopDishs"); + }); + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.DishComponent", b => { b.HasOne("FoodOrdersDatabaseImplement.Models.Component", "Component") @@ -151,6 +204,25 @@ namespace FoodOrdersDatabaseImplement.Migrations b.Navigation("Dish"); }); + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.ShopDish", b => + { + b.HasOne("FoodOrdersDatabaseImplement.Models.Dish", "Dish") + .WithMany("ShopDishs") + .HasForeignKey("DishId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("FoodOrdersDatabaseImplement.Models.Shop", "Shop") + .WithMany("Dishs") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Dish"); + + b.Navigation("Shop"); + }); + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Component", b => { b.Navigation("DishComponents"); @@ -161,6 +233,13 @@ namespace FoodOrdersDatabaseImplement.Migrations b.Navigation("Components"); b.Navigation("Orders"); + + b.Navigation("ShopDishs"); + }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Shop", b => + { + b.Navigation("Dishs"); }); #pragma warning restore 612, 618 } diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Models/Dish.cs b/FoodOrders/FoodOrdersDatabaseImplement/Models/Dish.cs index f889698..776f03b 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/Models/Dish.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/Models/Dish.cs @@ -38,6 +38,8 @@ namespace FoodOrdersDatabaseImplement.Models public virtual List Components { get; set; } = new(); [ForeignKey("DishId")] public virtual List Orders { get; set; } = new(); + [ForeignKey("DishId")] + public virtual List ShopDishs { get; set; } = new(); public static Dish? Create(FoodOrdersDatabase context, DishBindingModel model) { diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Models/Shop.cs b/FoodOrders/FoodOrdersDatabaseImplement/Models/Shop.cs new file mode 100644 index 0000000..6058c25 --- /dev/null +++ b/FoodOrders/FoodOrdersDatabaseImplement/Models/Shop.cs @@ -0,0 +1,110 @@ +using FoodOrdersContracts.BindingModels; +using FoodOrdersContracts.ViewModels; +using FoodOrdersDataModels.Models; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace FoodOrdersDatabaseImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; set; } + + [Required] + public string ShopName { get; set; } = string.Empty; + + [Required] + public string Address { get; set; } = string.Empty; + + [Required] + public DateTime DateOpening { get; set; } + + [Required] + public int MaxCountDishs { get; set; } + + private Dictionary? _shopDishs = null; + + [NotMapped] + public Dictionary ShopDishs + { + get + { + if (_shopDishs == null) + { + _shopDishs = Dishs + .ToDictionary(x => x.DishId, x => (x.Dish as IDishModel, x.Count)); + } + return _shopDishs; + } + } + + [ForeignKey("ShopId")] + public virtual List Dishs { get; set; } = new(); + + public static Shop Create(FoodOrdersDatabase context, ShopBindingModel model) + { + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOpening = model.DateOpening, + MaxCountDishs = model.MaxCountDishs, + Dishs = model.ShopDishs.Select(x => new ShopDish + { + Dish = context.Dishs.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; + MaxCountDishs = model.MaxCountDishs; + } + + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpening = DateOpening, + MaxCountDishs = MaxCountDishs, + ShopDishs = ShopDishs + }; + + public void UpdateDishs(FoodOrdersDatabase context, ShopBindingModel model) + { + var shopDishs = context.ShopDishs.Where(rec => rec.ShopId == model.Id).ToList(); + if (shopDishs != null && shopDishs.Count > 0) + { + context.ShopDishs.RemoveRange(shopDishs.Where(rec => !model.ShopDishs.ContainsKey(rec.DishId))); + context.SaveChanges(); + foreach (var updateDish in shopDishs) + { + if (model.ShopDishs.ContainsKey(updateDish.DishId)) + { + updateDish.Count = model.ShopDishs[updateDish.DishId].Item2; + model.ShopDishs.Remove(updateDish.DishId); + } + } + context.SaveChanges(); + } + var shop = context.Shops.First(x => x.Id == Id); + foreach (var ic in model.ShopDishs) + { + context.ShopDishs.Add(new ShopDish + { + Shop = shop, + Dish = context.Dishs.First(x => x.Id == ic.Key), + Count = ic.Value.Item2 + }); + context.SaveChanges(); + } + _shopDishs = null; + } + } +} diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Models/ShopDish.cs b/FoodOrders/FoodOrdersDatabaseImplement/Models/ShopDish.cs new file mode 100644 index 0000000..fa1cb06 --- /dev/null +++ b/FoodOrders/FoodOrdersDatabaseImplement/Models/ShopDish.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; + +namespace FoodOrdersDatabaseImplement.Models +{ + public class ShopDish + { + public int Id { get; set; } + + [Required] + public int ShopId { get; set; } + + [Required] + public int DishId { get; set; } + + [Required] + public int Count { get; set; } + + public virtual Dish Dish { get; set; } = new(); + + public virtual Shop Shop { get; set; } = new(); + } +} From 2502c81e43ddccfd0b1a985accc7567c61a03973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9F=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D1=86=D0=B5=D0=B2?= Date: Mon, 22 Apr 2024 11:19:24 +0400 Subject: [PATCH 7/8] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Implements/ShopStorage.cs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs b/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs index a5f1a52..0f6ba52 100644 --- a/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs +++ b/FoodOrders/FoodOrdersFileImplement/Implements/ShopStorage.cs @@ -85,20 +85,12 @@ namespace FoodOrdersFileImplement.Implements { var dish = source.Dishs.FirstOrDefault(x => x.Id == model.Id); - if (dish == null) - { - return false; - } + int countStore = source.Shops + .SelectMany(x => x.ShopDishs) + .Where(y => y.Key == model.Id) + .Sum(y => y.Value.Item2); - - var shopDishs = source.Shops.SelectMany(shop => shop.ShopDishs.Where(c => c.Value.Item1.Id == dish.Id)); - - int countStore = 0; - - foreach (var it in shopDishs) - countStore += it.Value.Item2; - - if (count > countStore) + if (dish == null || count > countStore) return false; foreach (var shop in source.Shops) From 8349b6188bc448b2695cd6837ff24f531f3f4182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9F=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D1=86=D0=B5=D0=B2?= Date: Mon, 22 Apr 2024 11:47:25 +0400 Subject: [PATCH 8/8] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FoodOrdersDatabaseImplement/Implemets/ShopStorage.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Implemets/ShopStorage.cs b/FoodOrders/FoodOrdersDatabaseImplement/Implemets/ShopStorage.cs index fa8e224..0f90ccb 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/Implemets/ShopStorage.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/Implemets/ShopStorage.cs @@ -114,15 +114,15 @@ namespace FoodOrdersDatabaseImplement.Implements .Where(x => x.Dishs.Any(x => x.DishId == model.Id)) .ToList()) { - var iceCream = shop.ShopDishs[model.Id]; - int min = Math.Min(iceCream.Item2, count); - if (min == iceCream.Item2) + var dish = shop.ShopDishs[model.Id]; + int min = Math.Min(dish.Item2, count); + if (min == dish.Item2) { shop.ShopDishs.Remove(model.Id); } else { - shop.ShopDishs[model.Id] = (iceCream.Item1, iceCream.Item2 - min); + shop.ShopDishs[model.Id] = (dish.Item1, dish.Item2 - min); } shop.UpdateDishs(context, new() { Id = shop.Id, ShopDishs = shop.ShopDishs }); count -= min;