From 1875896d5e8203b04e1f0b665dc3123f375025c9 Mon Sep 17 00:00:00 2001 From: abazov73 <92822431+abazov73@users.noreply.github.com> Date: Mon, 20 Feb 2023 10:34:37 +0400 Subject: [PATCH 1/5] =?UTF-8?q?=D0=92=D1=82=D0=BE=D1=80=D0=B0=D1=8F=20?= =?UTF-8?q?=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=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Confectionery/Confectionery.sln | 12 ++- .../Confectionery/Confectionery.csproj | 1 + Confectionery/Confectionery/Program.cs | 2 +- .../ConfectioneryFileImplement.csproj | 14 +++ .../DataFileSingleton.cs | 54 +++++++++++ .../Implements/IngredientStorage.cs | 86 +++++++++++++++++ .../Implements/OrderStorage.cs | 95 +++++++++++++++++++ .../Implements/PastryStorage.cs | 89 +++++++++++++++++ .../Models/Ingredient.cs | 62 ++++++++++++ .../Models/Order.cs | 91 ++++++++++++++++++ .../Models/Pastry.cs | 89 +++++++++++++++++ 11 files changed, 591 insertions(+), 4 deletions(-) create mode 100644 Confectionery/ConfectioneryFileImplements/ConfectioneryFileImplement.csproj create mode 100644 Confectionery/ConfectioneryFileImplements/DataFileSingleton.cs create mode 100644 Confectionery/ConfectioneryFileImplements/Implements/IngredientStorage.cs create mode 100644 Confectionery/ConfectioneryFileImplements/Implements/OrderStorage.cs create mode 100644 Confectionery/ConfectioneryFileImplements/Implements/PastryStorage.cs create mode 100644 Confectionery/ConfectioneryFileImplements/Models/Ingredient.cs create mode 100644 Confectionery/ConfectioneryFileImplements/Models/Order.cs create mode 100644 Confectionery/ConfectioneryFileImplements/Models/Pastry.cs diff --git a/Confectionery/Confectionery.sln b/Confectionery/Confectionery.sln index 2c453a2..dcd8aca 100644 --- a/Confectionery/Confectionery.sln +++ b/Confectionery/Confectionery.sln @@ -7,11 +7,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Confectionery", "Confection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryDataModels", "ConfectioneryDataModels\ConfectioneryDataModels.csproj", "{22A053DC-3DC2-4375-9563-BF647A1092A4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryContracts", "ConfectioneryContracts\ConfectioneryContracts.csproj", "{6C4950D1-D788-4D5A-8C15-0A376274F2DD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryContracts", "ConfectioneryContracts\ConfectioneryContracts.csproj", "{6C4950D1-D788-4D5A-8C15-0A376274F2DD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryBusinessLogic", "ConfectioneryBusinessLogic\ConfectioneryBusinessLogic.csproj", "{30F4AE5A-2C90-4C7F-BBE9-2FA56BE26C63}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryBusinessLogic", "ConfectioneryBusinessLogic\ConfectioneryBusinessLogic.csproj", "{30F4AE5A-2C90-4C7F-BBE9-2FA56BE26C63}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryListImplement", "ConfectioneryListImplement\ConfectioneryListImplement.csproj", "{85992074-656D-4F79-AB23-60DE4F9ABF30}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryListImplement", "ConfectioneryListImplement\ConfectioneryListImplement.csproj", "{85992074-656D-4F79-AB23-60DE4F9ABF30}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryFileImplement", "ConfectioneryFileImplements\ConfectioneryFileImplement.csproj", "{48A8592F-EF58-4FC4-9C9E-B401836FF21E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -39,6 +41,10 @@ Global {85992074-656D-4F79-AB23-60DE4F9ABF30}.Debug|Any CPU.Build.0 = Debug|Any CPU {85992074-656D-4F79-AB23-60DE4F9ABF30}.Release|Any CPU.ActiveCfg = Release|Any CPU {85992074-656D-4F79-AB23-60DE4F9ABF30}.Release|Any CPU.Build.0 = Release|Any CPU + {48A8592F-EF58-4FC4-9C9E-B401836FF21E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {48A8592F-EF58-4FC4-9C9E-B401836FF21E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {48A8592F-EF58-4FC4-9C9E-B401836FF21E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {48A8592F-EF58-4FC4-9C9E-B401836FF21E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Confectionery/Confectionery/Confectionery.csproj b/Confectionery/Confectionery/Confectionery.csproj index 0e7fb26..09d809e 100644 --- a/Confectionery/Confectionery/Confectionery.csproj +++ b/Confectionery/Confectionery/Confectionery.csproj @@ -31,6 +31,7 @@ + diff --git a/Confectionery/Confectionery/Program.cs b/Confectionery/Confectionery/Program.cs index c98764e..38ca50e 100644 --- a/Confectionery/Confectionery/Program.cs +++ b/Confectionery/Confectionery/Program.cs @@ -1,7 +1,7 @@ using ConfectioneryBusinessLogic.BusinessLogics; using ConfectioneryContracts.BusinessLogicsContracts; using ConfectioneryContracts.StoragesContracts; -using ConfectioneryListImplement.Implements; +using ConfectioneryFileImplement.Implements; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NLog.Extensions.Logging; diff --git a/Confectionery/ConfectioneryFileImplements/ConfectioneryFileImplement.csproj b/Confectionery/ConfectioneryFileImplements/ConfectioneryFileImplement.csproj new file mode 100644 index 0000000..68fca7e --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/ConfectioneryFileImplement.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/Confectionery/ConfectioneryFileImplements/DataFileSingleton.cs b/Confectionery/ConfectioneryFileImplements/DataFileSingleton.cs new file mode 100644 index 0000000..53fc38f --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/DataFileSingleton.cs @@ -0,0 +1,54 @@ +using ConfectioneryFileImplement.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ConfectioneryFileImplement +{ + public class DataFileSingleton + { + private static DataFileSingleton? instance; + private readonly string IngredientFileName = "Ingredient.xml"; + private readonly string OrderFileName = "Order.xml"; + private readonly string PastryFileName = "Pastry.xml"; + public List Ingredients { get; private set; } + public List Orders { get; private set; } + public List Pastries { get; private set; } + public static DataFileSingleton GetInstance() + { + if (instance == null) + { + instance = new DataFileSingleton(); + } + return instance; + } + public void SaveIngredients() => SaveData(Ingredients, IngredientFileName, "Ingredients", x => x.GetXElement); + public void SavePastries() => SaveData(Pastries, PastryFileName, "Pastries", x => x.GetXElement); + public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + private DataFileSingleton() + { + Ingredients = LoadData(IngredientFileName, "Ingredient", x => Ingredient.Create(x)!)!; + Pastries = LoadData(PastryFileName, "Pastry", x => Pastry.Create(x)!)!; + Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; + } + private static List? LoadData(string filename, string xmlNodeName, Func selectFunction) + { + if (File.Exists(filename)) + { + return XDocument.Load(filename)?.Root?.Elements(xmlNodeName)?.Select(selectFunction)?.ToList(); + } + return new List(); + } + private static void SaveData(List data, string filename, string xmlNodeName, Func selectFunction) + { + if (data != null) + { + new XDocument(new XElement(xmlNodeName, data.Select(selectFunction).ToArray())).Save(filename); + } + } + } +} diff --git a/Confectionery/ConfectioneryFileImplements/Implements/IngredientStorage.cs b/Confectionery/ConfectioneryFileImplements/Implements/IngredientStorage.cs new file mode 100644 index 0000000..934020f --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/Implements/IngredientStorage.cs @@ -0,0 +1,86 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryContracts.ViewModels; +using ConfectioneryFileImplement.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryFileImplement.Implements +{ + public class IngredientStorage : IIngredientStorage + { + private readonly DataFileSingleton source; + public IngredientStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Ingredients + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(IngredientSearchModel model) + { + if (string.IsNullOrEmpty(model.IngredientName)) + { + return new(); + } + return source.Ingredients + .Where(x => x.IngredientName.Contains(model.IngredientName)) + .Select(x => x.GetViewModel) + .ToList(); + } + public IngredientViewModel? GetElement(IngredientSearchModel model) + { + if (string.IsNullOrEmpty(model.IngredientName) && !model.Id.HasValue) + { + return null; + } + return source.Ingredients + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.IngredientName) && x.IngredientName == model.IngredientName) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + + public IngredientViewModel? Insert(IngredientBindingModel model) + { + model.Id = source.Ingredients.Count > 0 ? source.Ingredients.Max(x => x.Id) + 1 : 1; + var newIngredient = Ingredient.Create(model); + if (newIngredient == null) + { + return null; + } + source.Ingredients.Add(newIngredient); + source.SaveIngredients(); + return newIngredient.GetViewModel; + } + public IngredientViewModel? Update(IngredientBindingModel model) + { + var component = source.Ingredients.FirstOrDefault(x => x.Id == model.Id); + if (component == null) + { + return null; + } + component.Update(model); + source.SaveIngredients(); + return component.GetViewModel; + } + public IngredientViewModel? Delete(IngredientBindingModel model) + { + var element = source.Ingredients.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + source.Ingredients.Remove(element); + source.SaveIngredients(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/Confectionery/ConfectioneryFileImplements/Implements/OrderStorage.cs b/Confectionery/ConfectioneryFileImplements/Implements/OrderStorage.cs new file mode 100644 index 0000000..499f021 --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/Implements/OrderStorage.cs @@ -0,0 +1,95 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryContracts.ViewModels; +using ConfectioneryFileImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryFileImplement.Implements +{ + public class OrderStorage : IOrderStorage + { + private readonly DataFileSingleton source; + public OrderStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Orders + .Select(x => AccessPastryStorage(x.GetViewModel)) + .ToList(); + } + + public List GetFilteredList(OrderSearchModel model) + { + if (!model.Id.HasValue) + { + return new(); + } + return source.Orders + .Where(x => x.Id == model.Id) + .Select(x => AccessPastryStorage(x.GetViewModel)) + .ToList(); + } + + public OrderViewModel? GetElement(OrderSearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + return AccessPastryStorage(source.Orders + .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) + ?.GetViewModel); + } + + public OrderViewModel? Insert(OrderBindingModel model) + { + model.Id = source.Orders.Count > 0 ? source.Orders.Max(x => x.Id) + 1 : 1; + var newOrder = Order.Create(model); + if (newOrder == null) + { + return null; + } + source.Orders.Add(newOrder); + source.SaveOrders(); + return AccessPastryStorage(newOrder.GetViewModel); + } + + public OrderViewModel? Update(OrderBindingModel model) + { + var order = source.Orders.FirstOrDefault(x => x.Id == model.Id); + if (order == null) + { + return null; + } + order.Update(model); + source.SaveOrders(); + return AccessPastryStorage(order.GetViewModel); + } + + public OrderViewModel? Delete(OrderBindingModel model) + { + var element = source.Orders.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + source.Orders.Remove(element); + source.SaveOrders(); + return AccessPastryStorage(element.GetViewModel); + } + return null; + } + + public OrderViewModel AccessPastryStorage(OrderViewModel model) + { + string? pastryName = source.Pastries.FirstOrDefault(x => x.Id == model?.PastryId)?.PastryName; + if (pastryName != null) model.PastryName = pastryName; + return model; + } + } +} diff --git a/Confectionery/ConfectioneryFileImplements/Implements/PastryStorage.cs b/Confectionery/ConfectioneryFileImplements/Implements/PastryStorage.cs new file mode 100644 index 0000000..acda54c --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/Implements/PastryStorage.cs @@ -0,0 +1,89 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryContracts.ViewModels; +using ConfectioneryFileImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryFileImplement.Implements +{ + public class PastryStorage : IPastryStorage + { + private readonly DataFileSingleton source; + public PastryStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Pastries + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(PastrySearchModel model) + { + if (string.IsNullOrEmpty(model.PastryName)) + { + return new(); + } + return source.Pastries + .Where(x => x.PastryName.Contains(model.PastryName)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public PastryViewModel? GetElement(PastrySearchModel model) + { + if (string.IsNullOrEmpty(model.PastryName) && !model.Id.HasValue) + { + return null; + } + return source.Pastries + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.PastryName) && x.PastryName == model.PastryName) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + + public PastryViewModel? Insert(PastryBindingModel model) + { + model.Id = source.Pastries.Count > 0 ? source.Pastries.Max(x => x.Id) + 1 : 1; + var newPastry = Pastry.Create(model); + if (newPastry == null) + { + return null; + } + source.Pastries.Add(newPastry); + source.SavePastries(); + return newPastry.GetViewModel; + } + + public PastryViewModel? Update(PastryBindingModel model) + { + var pastry = source.Pastries.FirstOrDefault(x => x.Id == model.Id); + if (pastry == null) + { + return null; + } + pastry.Update(model); + source.SavePastries(); + return pastry.GetViewModel; + } + + public PastryViewModel? Delete(PastryBindingModel model) + { + var element = source.Pastries.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + source.Pastries.Remove(element); + source.SavePastries(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/Confectionery/ConfectioneryFileImplements/Models/Ingredient.cs b/Confectionery/ConfectioneryFileImplements/Models/Ingredient.cs new file mode 100644 index 0000000..ed8c0bd --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/Models/Ingredient.cs @@ -0,0 +1,62 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ConfectioneryFileImplement.Models +{ + public class Ingredient : IIngredientModel + { + public int Id { get; private set; } + public string IngredientName { get; private set; } = string.Empty; + public double Cost { get; set; } + public static Ingredient? Create(IngredientBindingModel model) + { + if (model == null) return null; + return new Ingredient() + { + Id = model.Id, + IngredientName = model.IngredientName, + Cost = model.Cost + }; + } + public static Ingredient? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Ingredient() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + IngredientName = element.Element("IngredientName")!.Value, + Cost = Convert.ToDouble(element.Element("Cost")!.Value) + }; + } + public void Update(IngredientBindingModel model) + { + if (model == null) + { + return; + } + IngredientName = model.IngredientName; + Cost = model.Cost; + } + public IngredientViewModel GetViewModel => new() + { + Id = Id, + IngredientName = IngredientName, + Cost = Cost + }; + public XElement GetXElement => new("Ingredient", + new XAttribute("Id", Id), + new XElement("IngredientName", IngredientName), + new XElement("Cost", Cost.ToString())); + } +} diff --git a/Confectionery/ConfectioneryFileImplements/Models/Order.cs b/Confectionery/ConfectioneryFileImplements/Models/Order.cs new file mode 100644 index 0000000..702e13a --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/Models/Order.cs @@ -0,0 +1,91 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Enums; +using ConfectioneryDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ConfectioneryFileImplement.Models +{ + public class Order : IOrderModel + { + public int Id { get; private set; } + public int PastryId { get; private set; } + public int Count { get; private set; } + public double Sum { get; private set; } + + public OrderStatus Status { get; private set; } + + public DateTime DateCreate { get; private set; } + + public DateTime? DateImplement { get; private set; } + + public static Order? Create(OrderBindingModel? model) + { + if (model == null) + { + return null; + } + return new Order() + { + Id = model.Id, + PastryId = model.PastryId, + Count = model.Count, + Sum = model.Sum, + Status = model.Status, + DateCreate = model.DateCreate, + DateImplement = model.DateImplement + }; + } + + public static Order? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Order() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + PastryId = Convert.ToInt32(element.Element("PastryId")!.Value), + Count = Convert.ToInt32(element.Element("Count")!.Value), + Sum = Convert.ToDouble(element.Element("Sum")!.Value), + Status = (OrderStatus) Convert.ToInt32(element.Element("Status")!.Value), + DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value), + DateImplement = Convert.ToDateTime(String.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null : element.Element("DateImplement")!.Value) + }; + } + + public void Update(OrderBindingModel model) + { + if (model == null) + { + return; + } + Status = model.Status; + if (model.DateImplement.HasValue) DateImplement = model.DateImplement; + } + public OrderViewModel GetViewModel => new() + { + Id = Id, + PastryId = PastryId, + Count = Count, + Sum = Sum, + Status = Status, + DateCreate = DateCreate, + DateImplement = DateImplement + }; + public XElement GetXElement => new("Order", + new XAttribute("Id", Id), + new XElement("PastryId", PastryId), + new XElement("Count", Count.ToString()), + new XElement("Sum", Sum.ToString()), + new XElement("Status", ((int)Status).ToString()), + new XElement("DateCreate", DateCreate.ToString()), + new XElement("DateImplement", DateImplement.ToString())); + } +} diff --git a/Confectionery/ConfectioneryFileImplements/Models/Pastry.cs b/Confectionery/ConfectioneryFileImplements/Models/Pastry.cs new file mode 100644 index 0000000..2bb7093 --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/Models/Pastry.cs @@ -0,0 +1,89 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ConfectioneryFileImplement.Models +{ + public class Pastry + { + public int Id { get; private set; } + public string PastryName { get; private set; } = string.Empty; + public double Price { get; private set; } + public Dictionary Ingredients { get; private set; } = new(); + private Dictionary? _pastryIngredients = null; + public Dictionary PastryIngredients + { + get + { + if (_pastryIngredients == null) + { + var source = DataFileSingleton.GetInstance(); + _pastryIngredients = Ingredients.ToDictionary(x => x.Key, y => ((source.Ingredients.FirstOrDefault(z => z.Id == y.Key) as IIngredientModel)!, y.Value)); + } + return _pastryIngredients; + } + } + public static Pastry? Create(PastryBindingModel model) + { + if (model == null) + { + return null; + } + return new Pastry() + { + Id = model.Id, + PastryName = model.PastryName, + Price = model.Price, + Ingredients = model.PastryIngredients.ToDictionary(x => x.Key, x => x.Value.Item2) + }; + } + + public static Pastry? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Pastry() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + PastryName = element.Element("PastryName")!.Value, + Price = Convert.ToDouble(element.Element("Price")!.Value), + Ingredients = element.Element("PastryIngredients")!.Elements("PastryIngredient").ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value)) + }; + } + + public void Update(PastryBindingModel model) + { + if (model == null) + { + return; + } + PastryName = model.PastryName; + Price = model.Price; + Ingredients = model.PastryIngredients.ToDictionary(x => x.Key, x => x.Value.Item2); + _pastryIngredients = null; + } + public PastryViewModel GetViewModel => new() + { + Id = Id, + PastryName = PastryName, + Price = Price, + PastryIngredients = PastryIngredients + }; + public XElement GetXElement => new("Pastry", + new XAttribute("Id", Id), + new XElement("PastryName", PastryName), + new XElement("Price", Price.ToString()), + new XElement("PastryIngredients", Ingredients.Select(x => new XElement("PastryIngredient", + new XElement("Key", x.Key), + new XElement("Value", x.Value))) + .ToArray())); + } +} -- 2.25.1 From 01e6d6c16879fd00dd3b3c5369bfa85de6afd3d5 Mon Sep 17 00:00:00 2001 From: abazov73 <92822431+abazov73@users.noreply.github.com> Date: Mon, 20 Feb 2023 10:46:32 +0400 Subject: [PATCH 2/5] =?UTF-8?q?=D0=92=D1=82=D0=BE=D1=80=D0=B0=D1=8F=20?= =?UTF-8?q?=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=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0.=20=D0=A4?= =?UTF-8?q?=D0=B8=D0=BA=D1=81=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE?= =?UTF-8?q?=D0=B9=20=D0=B2=20IngredientStorage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Implements/IngredientStorage.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Confectionery/ConfectioneryFileImplements/Implements/IngredientStorage.cs b/Confectionery/ConfectioneryFileImplements/Implements/IngredientStorage.cs index 934020f..721efda 100644 --- a/Confectionery/ConfectioneryFileImplements/Implements/IngredientStorage.cs +++ b/Confectionery/ConfectioneryFileImplements/Implements/IngredientStorage.cs @@ -62,14 +62,14 @@ namespace ConfectioneryFileImplement.Implements } public IngredientViewModel? Update(IngredientBindingModel model) { - var component = source.Ingredients.FirstOrDefault(x => x.Id == model.Id); - if (component == null) + var ingredient = source.Ingredients.FirstOrDefault(x => x.Id == model.Id); + if (ingredient == null) { return null; } - component.Update(model); + ingredient.Update(model); source.SaveIngredients(); - return component.GetViewModel; + return ingredient.GetViewModel; } public IngredientViewModel? Delete(IngredientBindingModel model) { -- 2.25.1 From cce2b9f879c3cf90342b70a8113afdaf20b5d675 Mon Sep 17 00:00:00 2001 From: abazov73 <92822431+abazov73@users.noreply.github.com> Date: Wed, 26 Apr 2023 23:58:53 +0400 Subject: [PATCH 3/5] =?UTF-8?q?=D0=92=D1=82=D0=BE=D1=80=D0=B0=D1=8F=20?= =?UTF-8?q?=D1=83=D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D1=91=D0=BD=D0=BD=D0=B0?= =?UTF-8?q?=D1=8F=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=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Confectionery/FormShop.Designer.cs | 30 +++- Confectionery/Confectionery/FormShop.cs | 7 + .../BusinessLogics/OrderLogic.cs | 7 +- .../BusinessLogics/ShopLogic.cs | 7 +- .../BindingModels/ShopBindingModel.cs | 1 + .../StoragesContracts/IShopStorage.cs | 3 + .../ViewModels/ShopViewModel.cs | 2 + .../Models/IShopModel.cs | 1 + .../DataFileSingleton.cs | 4 + .../Implements/ShopStorage.cs | 166 ++++++++++++++++++ .../Models/Pastry.cs | 2 +- .../Models/Shop.cs | 104 +++++++++++ .../Implements/ShopStorage.cs | 11 ++ .../ConfectioneryListImplement/Models/Shop.cs | 8 +- 14 files changed, 344 insertions(+), 9 deletions(-) create mode 100644 Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs create mode 100644 Confectionery/ConfectioneryFileImplements/Models/Shop.cs diff --git a/Confectionery/Confectionery/FormShop.Designer.cs b/Confectionery/Confectionery/FormShop.Designer.cs index 1cdb588..d304929 100644 --- a/Confectionery/Confectionery/FormShop.Designer.cs +++ b/Confectionery/Confectionery/FormShop.Designer.cs @@ -40,6 +40,8 @@ this.PastryId = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.PastryName = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.Count = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.textBoxCapacity = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.SuspendLayout(); // @@ -77,7 +79,7 @@ // // buttonCancel // - this.buttonCancel.Location = new System.Drawing.Point(376, 276); + this.buttonCancel.Location = new System.Drawing.Point(376, 313); this.buttonCancel.Name = "buttonCancel"; this.buttonCancel.Size = new System.Drawing.Size(94, 29); this.buttonCancel.TabIndex = 7; @@ -87,7 +89,7 @@ // // buttonSave // - this.buttonSave.Location = new System.Drawing.Point(276, 276); + this.buttonSave.Location = new System.Drawing.Point(276, 313); this.buttonSave.Name = "buttonSave"; this.buttonSave.Size = new System.Drawing.Size(94, 29); this.buttonSave.TabIndex = 6; @@ -120,7 +122,7 @@ this.PastryId, this.PastryName, this.Count}); - this.dataGridView.Location = new System.Drawing.Point(120, 105); + this.dataGridView.Location = new System.Drawing.Point(120, 142); this.dataGridView.MultiSelect = false; this.dataGridView.Name = "dataGridView"; this.dataGridView.RowHeadersVisible = false; @@ -155,11 +157,29 @@ this.Count.ReadOnly = true; this.Count.Width = 125; // + // textBoxCapacity + // + this.textBoxCapacity.Location = new System.Drawing.Point(120, 105); + this.textBoxCapacity.Name = "textBoxCapacity"; + this.textBoxCapacity.Size = new System.Drawing.Size(350, 27); + this.textBoxCapacity.TabIndex = 16; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(11, 108); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(103, 20); + this.label3.TabIndex = 15; + this.label3.Text = "Вместимость:"; + // // FormShop // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(478, 317); + this.ClientSize = new System.Drawing.Size(478, 354); + this.Controls.Add(this.textBoxCapacity); + this.Controls.Add(this.label3); this.Controls.Add(this.dataGridView); this.Controls.Add(this.label2); this.Controls.Add(this.openingDateTimePicker); @@ -192,5 +212,7 @@ private DataGridViewTextBoxColumn PastryId; private DataGridViewTextBoxColumn PastryName; private DataGridViewTextBoxColumn Count; + private TextBox textBoxCapacity; + private Label label3; } } \ No newline at end of file diff --git a/Confectionery/Confectionery/FormShop.cs b/Confectionery/Confectionery/FormShop.cs index 8e48dbc..a1a749f 100644 --- a/Confectionery/Confectionery/FormShop.cs +++ b/Confectionery/Confectionery/FormShop.cs @@ -43,6 +43,11 @@ namespace Confectionery MessageBox.Show("Заполните адрес", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } + if (string.IsNullOrEmpty(textBoxCapacity.Text)) + { + MessageBox.Show("Заполните вместимость", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } _logger.LogInformation("Сохранение магазина"); try { @@ -52,6 +57,7 @@ namespace Confectionery ShopName = textBoxName.Text, ShopAdress = textBoxAdress.Text, OpeningDate = openingDateTimePicker.Value.Date, + PastryCapacity = Convert.ToInt32(textBoxCapacity.Text), ShopPastries = _shopPastries }; var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model); @@ -83,6 +89,7 @@ namespace Confectionery textBoxName.Text = view.ShopName; textBoxAdress.Text = view.ShopAdress; openingDateTimePicker.Value = view.OpeningDate; + textBoxCapacity.Text = view.PastryCapacity.ToString(); _shopPastries = view.ShopPastries; foreach (var pc in view.ShopPastries) { diff --git a/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/OrderLogic.cs b/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/OrderLogic.cs index f35b2ce..aa757af 100644 --- a/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/OrderLogic.cs @@ -17,11 +17,13 @@ namespace ConfectioneryBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; + private readonly IShopStorage _shopStorage; - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IShopStorage shopStorage) { _logger = logger; _orderStorage = orderStorage; + _shopStorage = shopStorage; } public bool CreateOrder(OrderBindingModel model) @@ -54,6 +56,7 @@ namespace ConfectioneryBusinessLogic.BusinessLogics _logger.LogWarning("Status change operation failed"); throw new InvalidOperationException("Заказ должен быть переведен в статус готовности перед выдачей!"); } + model.Status = OrderStatus.Выдан; model.DateImplement = DateTime.Now; _orderStorage.Update(model); @@ -77,6 +80,8 @@ namespace ConfectioneryBusinessLogic.BusinessLogics _logger.LogWarning("Status change operation failed"); throw new InvalidOperationException("Заказ должен быть переведен в статус выполнения перед готовностью!"); } + bool hasFreeSpace = _shopStorage.Supply(element.PastryId, element.Count); + if (!hasFreeSpace) throw new InvalidOperationException("В магазинах недостаточно места, чтобы вместить данный заказ!"); model.Status = OrderStatus.Готов; _orderStorage.Update(model); return true; diff --git a/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/ShopLogic.cs b/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/ShopLogic.cs index 1ba2248..c4b8908 100644 --- a/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/ShopLogic.cs +++ b/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/ShopLogic.cs @@ -106,6 +106,10 @@ namespace ConfectioneryBusinessLogic.BusinessLogics { throw new ArgumentNullException("Нет адресса иагазина", nameof(model.ShopAdress)); } + if (model.PastryCapacity <= 0) + { + throw new InvalidOperationException("Вместимоcть должна быть больше 0"); + } _logger.LogInformation("Shop. ShopName:{ShopName}. Id:{Id}", model.ShopName, model.Id); var element = _shopStorage.GetElement(new ShopSearchModel { @@ -152,7 +156,8 @@ namespace ConfectioneryBusinessLogic.BusinessLogics ShopName = element.ShopName, ShopAdress = element.ShopAdress, OpeningDate = element.OpeningDate, - ShopPastries = element.ShopPastries + ShopPastries = element.ShopPastries, + PastryCapacity = element.PastryCapacity }); return true; } diff --git a/Confectionery/ConfectioneryContracts/BindingModels/ShopBindingModel.cs b/Confectionery/ConfectioneryContracts/BindingModels/ShopBindingModel.cs index fcaec17..c21554a 100644 --- a/Confectionery/ConfectioneryContracts/BindingModels/ShopBindingModel.cs +++ b/Confectionery/ConfectioneryContracts/BindingModels/ShopBindingModel.cs @@ -12,6 +12,7 @@ namespace ConfectioneryContracts.BindingModels public int Id { get; set; } public string ShopName { get; set; } = string.Empty; public string ShopAdress { get; set; } = string.Empty; + public int PastryCapacity { get; set; } public DateTime OpeningDate { get; set; } public Dictionary ShopPastries { diff --git a/Confectionery/ConfectioneryContracts/StoragesContracts/IShopStorage.cs b/Confectionery/ConfectioneryContracts/StoragesContracts/IShopStorage.cs index 86d0e18..fe832ea 100644 --- a/Confectionery/ConfectioneryContracts/StoragesContracts/IShopStorage.cs +++ b/Confectionery/ConfectioneryContracts/StoragesContracts/IShopStorage.cs @@ -1,6 +1,7 @@ using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.SearchModels; using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.Linq; @@ -17,5 +18,7 @@ namespace ConfectioneryContracts.StoragesContracts ShopViewModel? Insert(ShopBindingModel model); ShopViewModel? Update(ShopBindingModel model); ShopViewModel? Delete(ShopBindingModel model); + bool Supply(int pastryId, int count); + bool Sell(int pastryId, int count); } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/ShopViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/ShopViewModel.cs index d904197..7d5b1fe 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/ShopViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/ShopViewModel.cs @@ -17,6 +17,8 @@ namespace ConfectioneryContracts.ViewModels public string ShopAdress { get; set; } = String.Empty; [DisplayName("Дата открытия")] public DateTime OpeningDate { get; set; } + [DisplayName("Макс. вместимость")] + public int PastryCapacity { get; set; } public Dictionary ShopPastries { get; diff --git a/Confectionery/ConfectioneryDataModels/Models/IShopModel.cs b/Confectionery/ConfectioneryDataModels/Models/IShopModel.cs index 307a2eb..26c6a01 100644 --- a/Confectionery/ConfectioneryDataModels/Models/IShopModel.cs +++ b/Confectionery/ConfectioneryDataModels/Models/IShopModel.cs @@ -10,6 +10,7 @@ namespace ConfectioneryDataModels.Models { string ShopName { get; } string ShopAdress { get; } + int PastryCapacity { get; } DateTime OpeningDate { get; } Dictionary ShopPastries { get; } } diff --git a/Confectionery/ConfectioneryFileImplements/DataFileSingleton.cs b/Confectionery/ConfectioneryFileImplements/DataFileSingleton.cs index 53fc38f..91a7f6b 100644 --- a/Confectionery/ConfectioneryFileImplements/DataFileSingleton.cs +++ b/Confectionery/ConfectioneryFileImplements/DataFileSingleton.cs @@ -15,9 +15,11 @@ namespace ConfectioneryFileImplement private readonly string IngredientFileName = "Ingredient.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string PastryFileName = "Pastry.xml"; + private readonly string ShopFileName = "Shop.xml"; public List Ingredients { get; private set; } public List Orders { get; private set; } public List Pastries { get; private set; } + public List Shops { get; private set; } public static DataFileSingleton GetInstance() { if (instance == null) @@ -29,11 +31,13 @@ namespace ConfectioneryFileImplement public void SaveIngredients() => SaveData(Ingredients, IngredientFileName, "Ingredients", x => x.GetXElement); public void SavePastries() => SaveData(Pastries, PastryFileName, "Pastries", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", x => x.GetXElement); private DataFileSingleton() { Ingredients = LoadData(IngredientFileName, "Ingredient", x => Ingredient.Create(x)!)!; Pastries = LoadData(PastryFileName, "Pastry", x => Pastry.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/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs b/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs new file mode 100644 index 0000000..89f46c2 --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs @@ -0,0 +1,166 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; +using ConfectioneryFileImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryFileImplement.Implements +{ + public class ShopStorage : IShopStorage + { + private readonly DataFileSingleton source; + public ShopStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Shops + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName)) + { + return new(); + } + return source.Shops + .Where(x => x.ShopName.Contains(model.ShopName)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue) + { + return null; + } + return source.Shops + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) && x.ShopName == model.ShopName) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + model.Id = source.Shops.Count > 0 ? source.Shops.Max(x => x.Id) + 1 : 1; + var newShop = Shop.Create(model); + if (newShop == null) + { + return null; + } + source.Shops.Add(newShop); + source.SaveShops(); + return newShop.GetViewModel; + } + + public ShopViewModel? Update(ShopBindingModel model) + { + var pastry = source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (pastry == null) + { + return null; + } + pastry.Update(model); + source.SaveShops(); + return pastry.GetViewModel; + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + var element = source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + source.Shops.Remove(element); + source.SaveShops(); + return element.GetViewModel; + } + return null; + } + + public bool Supply(int pastryId, int count) + { + int freeSpace = source.Shops.Select(x => x.PastryCapacity - x.ShopPastries.Select(y => y.Value.Item2).Sum()).Sum(); + if (freeSpace < count) + { + return false; + } + foreach (Shop shop in source.Shops){ + int freeShopSpace = shop.PastryCapacity - shop.ShopPastries.Select(y => y.Value.Item2).Sum(); + if (freeShopSpace > 0) + { + if (freeShopSpace >= count) + { + if (shop.Pastries.ContainsKey(pastryId)) + { + shop.Pastries[pastryId] += count; + } + else + { + shop.Pastries.Add(pastryId, count); + } + shop.setShopPastriesNull(); + return true; + } + else + { + int dif = count - freeShopSpace; + count -= freeShopSpace; + if (shop.Pastries.TryGetValue(pastryId, out var pastryCount)) + { + shop.Pastries[pastryId] = pastryCount + count; + } + else + { + shop.Pastries.Add(pastryId, count); + } + shop.setShopPastriesNull(); + } + } + } + return false; + } + + public bool Sell(int pastryId, int count) + { + int pastryCount = source.Shops.Select(x => x.ShopPastries.Select(y => y.Value).Where(y => y.Item1.Id == pastryId).Sum(y => y.Item2)).Sum(); + if (pastryCount < count) + { + return false; + } + foreach (Shop shop in source.Shops) + { + int shopPastryCount = shop.ShopPastries.Select(x => x.Value).Where(x => x.Item1.Id == pastryId).Sum(x => x.Item2); + if (count - shopPastryCount >= 0) + { + count -= shopPastryCount; + shop.Pastries.Remove(pastryId); + shop.setShopPastriesNull(); + } + else + { + count = 0; + shop.Pastries[pastryId] -= count; + shop.setShopPastriesNull(); + } + if (count == 0) + { + source.SaveShops(); + return true; + } + } + return false; + } + } +} diff --git a/Confectionery/ConfectioneryFileImplements/Models/Pastry.cs b/Confectionery/ConfectioneryFileImplements/Models/Pastry.cs index 2bb7093..c9581d0 100644 --- a/Confectionery/ConfectioneryFileImplements/Models/Pastry.cs +++ b/Confectionery/ConfectioneryFileImplements/Models/Pastry.cs @@ -10,7 +10,7 @@ using System.Xml.Linq; namespace ConfectioneryFileImplement.Models { - public class Pastry + public class Pastry : IPastryModel { public int Id { get; private set; } public string PastryName { get; private set; } = string.Empty; diff --git a/Confectionery/ConfectioneryFileImplements/Models/Shop.cs b/Confectionery/ConfectioneryFileImplements/Models/Shop.cs new file mode 100644 index 0000000..b9be455 --- /dev/null +++ b/Confectionery/ConfectioneryFileImplements/Models/Shop.cs @@ -0,0 +1,104 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ConfectioneryFileImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + public string ShopName { get; private set; } = string.Empty; + public string ShopAdress { get; private set; } = string.Empty; + public int PastryCapacity { get; private set; } + public DateTime OpeningDate { get; private set; } + public Dictionary Pastries { get; private set; } = new(); + private Dictionary? _shopPastries = null; + public Dictionary ShopPastries + { + get + { + if (_shopPastries == null) + { + var source = DataFileSingleton.GetInstance(); + _shopPastries = Pastries.ToDictionary(x => x.Key, y => ((source.Pastries.FirstOrDefault(z => z.Id == y.Key) as IPastryModel)!, y.Value)); + } + return _shopPastries; + } + } + public static Shop? Create(ShopBindingModel? model) + { + if (model == null) + { + return null; + } + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + ShopAdress = model.ShopAdress, + OpeningDate = model.OpeningDate, + Pastries = model.ShopPastries.ToDictionary(x => x.Key, x => x.Value.Item2), + PastryCapacity = model.PastryCapacity + }; + } + 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, + ShopAdress = element.Element("ShopAdress")!.Value, + PastryCapacity = Convert.ToInt32(element.Element("PastryCapacity")!.Value), + OpeningDate = Convert.ToDateTime(element.Element("OpeningDate")!.Value), + Pastries = element.Element("ShopPastries")!.Elements("ShopPastry").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; + ShopAdress = model.ShopAdress; + OpeningDate = model.OpeningDate; + Pastries = model.ShopPastries.ToDictionary(x => x.Key, x => x.Value.Item2); + _shopPastries = null; + PastryCapacity = model.PastryCapacity; + } + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + ShopAdress = ShopAdress, + ShopPastries = ShopPastries, + OpeningDate = OpeningDate, + PastryCapacity = PastryCapacity, + }; + internal void setShopPastriesNull() + { + _shopPastries = null; + } + public XElement GetXElement => new("Shop", + new XAttribute("Id", Id), + new XElement("ShopName", ShopName), + new XElement("ShopAdress", ShopAdress), + new XElement("PastryCapacity", PastryCapacity.ToString()), + new XElement("OpeningDate", OpeningDate.ToString()), + new XElement("ShopPastries", Pastries.Select(x => new XElement("ShopPastry", + new XElement("Key", x.Key), + new XElement("Value", x.Value))) + .ToArray())); + } +} diff --git a/Confectionery/ConfectioneryListImplement/Implements/ShopStorage.cs b/Confectionery/ConfectioneryListImplement/Implements/ShopStorage.cs index f95cb0a..6e89a0d 100644 --- a/Confectionery/ConfectioneryListImplement/Implements/ShopStorage.cs +++ b/Confectionery/ConfectioneryListImplement/Implements/ShopStorage.cs @@ -2,6 +2,7 @@ using ConfectioneryContracts.SearchModels; using ConfectioneryContracts.StoragesContracts; using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; using ConfectioneryListImplement.Models; using System; using System.Collections.Generic; @@ -107,5 +108,15 @@ namespace ConfectioneryListImplement.Implements } return null; } + + public bool Supply(int pastryId, int count) + { + throw new NotImplementedException(); + } + + public bool Sell(int pastryId, int count) + { + throw new NotImplementedException(); + } } } diff --git a/Confectionery/ConfectioneryListImplement/Models/Shop.cs b/Confectionery/ConfectioneryListImplement/Models/Shop.cs index c264be8..56a5728 100644 --- a/Confectionery/ConfectioneryListImplement/Models/Shop.cs +++ b/Confectionery/ConfectioneryListImplement/Models/Shop.cs @@ -15,6 +15,7 @@ namespace ConfectioneryListImplement.Models public int Id { get; private set; } public string ShopName { get; private set; } = string.Empty; public string ShopAdress { get; private set; } = string.Empty; + public int PastryCapacity { get; private set; } public DateTime OpeningDate { get; private set; } public Dictionary ShopPastries { get; private set; } = new Dictionary(); public static Shop? Create(ShopBindingModel? model) @@ -29,7 +30,8 @@ namespace ConfectioneryListImplement.Models ShopName = model.ShopName, ShopAdress = model.ShopAdress, OpeningDate = model.OpeningDate, - ShopPastries = model.ShopPastries + ShopPastries = model.ShopPastries, + PastryCapacity = model.PastryCapacity }; } public void Update(ShopBindingModel? model) @@ -42,6 +44,7 @@ namespace ConfectioneryListImplement.Models ShopAdress = model.ShopAdress; OpeningDate = model.OpeningDate; ShopPastries = model.ShopPastries; + PastryCapacity = model.PastryCapacity; } public ShopViewModel GetViewModel => new() { @@ -49,7 +52,8 @@ namespace ConfectioneryListImplement.Models ShopName = ShopName, ShopAdress = ShopAdress, ShopPastries = ShopPastries, - OpeningDate = OpeningDate + OpeningDate = OpeningDate, + PastryCapacity = PastryCapacity, }; } } -- 2.25.1 From 9f36212f5a009328b9d72f5bb80b6a995053325c Mon Sep 17 00:00:00 2001 From: abazov73 <92822431+abazov73@users.noreply.github.com> Date: Fri, 12 May 2023 23:34:17 +0400 Subject: [PATCH 4/5] Sell form + sell operation fix --- .../Confectionery/FormMain.Designer.cs | 24 +++- Confectionery/Confectionery/FormMain.cs | 9 ++ .../Confectionery/FormSell.Designer.cs | 120 ++++++++++++++++++ Confectionery/Confectionery/FormSell.cs | 82 ++++++++++++ Confectionery/Confectionery/FormSell.resx | 60 +++++++++ Confectionery/Confectionery/Program.cs | 1 + .../BusinessLogics/ShopLogic.cs | 5 + .../BusinessLogicsContracts/IShopLogic.cs | 1 + .../Implements/ShopStorage.cs | 2 +- 9 files changed, 296 insertions(+), 8 deletions(-) create mode 100644 Confectionery/Confectionery/FormSell.Designer.cs create mode 100644 Confectionery/Confectionery/FormSell.cs create mode 100644 Confectionery/Confectionery/FormSell.resx diff --git a/Confectionery/Confectionery/FormMain.Designer.cs b/Confectionery/Confectionery/FormMain.Designer.cs index f2e480d..2d92211 100644 --- a/Confectionery/Confectionery/FormMain.Designer.cs +++ b/Confectionery/Confectionery/FormMain.Designer.cs @@ -33,13 +33,14 @@ this.ингредиентыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.изделияToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.магазиныToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.пополнениеМагазинаToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.dataGridView = new System.Windows.Forms.DataGridView(); this.buttonCreateOrder = new System.Windows.Forms.Button(); this.buttonTakeOrderInWork = new System.Windows.Forms.Button(); this.buttonOrderReady = new System.Windows.Forms.Button(); this.buttonIssuedOrder = new System.Windows.Forms.Button(); this.buttonRef = new System.Windows.Forms.Button(); - this.пополнениеМагазинаToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.списаниеToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.SuspendLayout(); @@ -49,7 +50,8 @@ this.menuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.справочникиToolStripMenuItem, - this.пополнениеМагазинаToolStripMenuItem}); + this.пополнениеМагазинаToolStripMenuItem, + this.списаниеToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Size = new System.Drawing.Size(1238, 28); @@ -87,6 +89,13 @@ this.магазиныToolStripMenuItem.Text = "Магазины"; this.магазиныToolStripMenuItem.Click += new System.EventHandler(this.магазиныToolStripMenuItem_Click); // + // пополнениеМагазинаToolStripMenuItem + // + this.пополнениеМагазинаToolStripMenuItem.Name = "пополнениеМагазинаToolStripMenuItem"; + this.пополнениеМагазинаToolStripMenuItem.Size = new System.Drawing.Size(182, 24); + this.пополнениеМагазинаToolStripMenuItem.Text = "Пополнение магазина"; + this.пополнениеМагазинаToolStripMenuItem.Click += new System.EventHandler(this.пополнениеМагазинаToolStripMenuItem_Click); + // // dataGridView // this.dataGridView.BackgroundColor = System.Drawing.Color.White; @@ -150,12 +159,12 @@ this.buttonRef.UseVisualStyleBackColor = true; this.buttonRef.Click += new System.EventHandler(this.buttonRef_Click); // - // пополнениеМагазинаToolStripMenuItem + // списаниеToolStripMenuItem // - this.пополнениеМагазинаToolStripMenuItem.Name = "пополнениеМагазинаToolStripMenuItem"; - this.пополнениеМагазинаToolStripMenuItem.Size = new System.Drawing.Size(182, 24); - this.пополнениеМагазинаToolStripMenuItem.Text = "Пополнение магазина"; - this.пополнениеМагазинаToolStripMenuItem.Click += new System.EventHandler(this.пополнениеМагазинаToolStripMenuItem_Click); + this.списаниеToolStripMenuItem.Name = "списаниеToolStripMenuItem"; + this.списаниеToolStripMenuItem.Size = new System.Drawing.Size(91, 24); + this.списаниеToolStripMenuItem.Text = "Списание"; + this.списаниеToolStripMenuItem.Click += new System.EventHandler(this.списаниеToolStripMenuItem_Click); // // FormMain // @@ -195,5 +204,6 @@ private Button buttonRef; private ToolStripMenuItem магазиныToolStripMenuItem; private ToolStripMenuItem пополнениеМагазинаToolStripMenuItem; + private ToolStripMenuItem списаниеToolStripMenuItem; } } \ No newline at end of file diff --git a/Confectionery/Confectionery/FormMain.cs b/Confectionery/Confectionery/FormMain.cs index 390c971..3b01002 100644 --- a/Confectionery/Confectionery/FormMain.cs +++ b/Confectionery/Confectionery/FormMain.cs @@ -170,5 +170,14 @@ namespace Confectionery form.ShowDialog(); } } + + private void списаниеToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormSell)); + if (service is FormSell form) + { + form.ShowDialog(); + } + } } } diff --git a/Confectionery/Confectionery/FormSell.Designer.cs b/Confectionery/Confectionery/FormSell.Designer.cs new file mode 100644 index 0000000..61fa897 --- /dev/null +++ b/Confectionery/Confectionery/FormSell.Designer.cs @@ -0,0 +1,120 @@ +namespace Confectionery +{ + partial class FormSell + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.comboBoxPastry = new System.Windows.Forms.ComboBox(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.buttonCreate = new System.Windows.Forms.Button(); + this.textBoxSum = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // comboBoxPastry + // + this.comboBoxPastry.FormattingEnabled = true; + this.comboBoxPastry.Location = new System.Drawing.Point(129, 6); + this.comboBoxPastry.Name = "comboBoxPastry"; + this.comboBoxPastry.Size = new System.Drawing.Size(219, 28); + this.comboBoxPastry.TabIndex = 22; + // + // buttonCancel + // + this.buttonCancel.Location = new System.Drawing.Point(254, 92); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(94, 29); + this.buttonCancel.TabIndex = 21; + this.buttonCancel.Text = "Отмена"; + this.buttonCancel.UseVisualStyleBackColor = true; + this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); + // + // buttonCreate + // + this.buttonCreate.Location = new System.Drawing.Point(142, 92); + this.buttonCreate.Name = "buttonCreate"; + this.buttonCreate.Size = new System.Drawing.Size(94, 29); + this.buttonCreate.TabIndex = 20; + this.buttonCreate.Text = "Создать"; + this.buttonCreate.UseVisualStyleBackColor = true; + this.buttonCreate.Click += new System.EventHandler(this.buttonCreate_Click); + // + // textBoxSum + // + this.textBoxSum.Location = new System.Drawing.Point(129, 46); + this.textBoxSum.Name = "textBoxSum"; + this.textBoxSum.Size = new System.Drawing.Size(219, 27); + this.textBoxSum.TabIndex = 19; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(12, 49); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(93, 20); + this.label3.TabIndex = 18; + this.label3.Text = "Количество:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 9); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(71, 20); + this.label2.TabIndex = 17; + this.label2.Text = "Изделие:"; + // + // FormSell + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(360, 129); + this.Controls.Add(this.comboBoxPastry); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonCreate); + this.Controls.Add(this.textBoxSum); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Name = "FormSell"; + this.Text = "Продажа"; + this.Load += new System.EventHandler(this.FormSell_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ComboBox comboBoxPastry; + private Button buttonCancel; + private Button buttonCreate; + private TextBox textBoxSum; + private Label label3; + private Label label2; + } +} \ No newline at end of file diff --git a/Confectionery/Confectionery/FormSell.cs b/Confectionery/Confectionery/FormSell.cs new file mode 100644 index 0000000..9380f58 --- /dev/null +++ b/Confectionery/Confectionery/FormSell.cs @@ -0,0 +1,82 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.ViewModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Confectionery +{ + public partial class FormSell : Form + { + private readonly ILogger _logger; + private readonly IPastryLogic _logicP; + private readonly IShopLogic _logicS; + private List? _listPastry; + public FormSell(ILogger logger, IPastryLogic logicP, IShopLogic logicS) + { + InitializeComponent(); + _logger = logger; + _logicP = logicP; + _logicS = logicS; + } + + private void buttonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + + private void buttonCreate_Click(object sender, EventArgs e) + { + if (comboBoxPastry.SelectedValue == null) + { + MessageBox.Show("Выберите изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (String.IsNullOrEmpty(textBoxSum.Text)) + { + MessageBox.Show("Заполните поле количество!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + try + { + int count = Convert.ToInt32(textBoxSum.Text); + bool operationResult = _logicS.Sell(Convert.ToInt32(comboBoxPastry.SelectedValue), count); + if (!operationResult) + { + throw new Exception("Ошибка при создании поставки. Дополнительная информация в логах."); + } + MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + DialogResult = DialogResult.OK; + Close(); + + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка создания поставки!"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void FormSell_Load(object sender, EventArgs e) + { + _logger.LogInformation("Загрузка изделий для поставки"); + _listPastry = _logicP.ReadList(null); + if (_listPastry != null) + { + comboBoxPastry.DisplayMember = "PastryName"; + comboBoxPastry.ValueMember = "Id"; + comboBoxPastry.DataSource = _listPastry; + comboBoxPastry.SelectedItem = null; + } + } + } +} diff --git a/Confectionery/Confectionery/FormSell.resx b/Confectionery/Confectionery/FormSell.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/Confectionery/Confectionery/FormSell.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Confectionery/Confectionery/Program.cs b/Confectionery/Confectionery/Program.cs index 03d458e..9bd00dc 100644 --- a/Confectionery/Confectionery/Program.cs +++ b/Confectionery/Confectionery/Program.cs @@ -53,6 +53,7 @@ namespace Confectionery services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file diff --git a/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/ShopLogic.cs b/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/ShopLogic.cs index c4b8908..04f45e9 100644 --- a/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/ShopLogic.cs +++ b/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/ShopLogic.cs @@ -161,5 +161,10 @@ namespace ConfectioneryBusinessLogic.BusinessLogics }); return true; } + + public bool Sell(int pastryId, int count) + { + return _shopStorage.Sell(pastryId, count); + } } } diff --git a/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IShopLogic.cs b/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IShopLogic.cs index 24b6427..c6f1006 100644 --- a/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IShopLogic.cs +++ b/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IShopLogic.cs @@ -18,5 +18,6 @@ namespace ConfectioneryContracts.BusinessLogicsContracts bool Update(ShopBindingModel model); bool Delete(ShopBindingModel model); bool DeliverPastryToShop(ShopBindingModel shopModel, IPastryModel pastryModel, int count); + bool Sell(int pastryId, int count); } } diff --git a/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs b/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs index 89f46c2..214c74f 100644 --- a/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs +++ b/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs @@ -150,8 +150,8 @@ namespace ConfectioneryFileImplement.Implements } else { - count = 0; shop.Pastries[pastryId] -= count; + count = 0; shop.setShopPastriesNull(); } if (count == 0) -- 2.25.1 From ee4962b0d579340c3809de2fcadb6749f408c17f Mon Sep 17 00:00:00 2001 From: abazov73 <92822431+abazov73@users.noreply.github.com> Date: Mon, 15 May 2023 10:43:46 +0400 Subject: [PATCH 5/5] =?UTF-8?q?=D0=92=D1=82=D0=BE=D1=80=D0=B0=D1=8F=20?= =?UTF-8?q?=D1=83=D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D1=91=D0=BD=D0=BD=D0=B0?= =?UTF-8?q?=D1=8F=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=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0.=20?= =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BF=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20+=20=D1=84=D0=B8=D0=BA=D1=81=20?= =?UTF-8?q?=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B2=20=D1=84=D0=BE=D1=80=D0=BC=D0=B5=20=D1=81?= =?UTF-8?q?=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Confectionery/Confectionery/FormSell.cs | 2 +- .../ConfectioneryFileImplements/Implements/ShopStorage.cs | 5 ++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index ca1c7a3..e41ed9d 100644 --- a/.gitignore +++ b/.gitignore @@ -398,3 +398,4 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml +/Confectionery/ImplementationExtensions diff --git a/Confectionery/Confectionery/FormSell.cs b/Confectionery/Confectionery/FormSell.cs index 9380f58..db1c49d 100644 --- a/Confectionery/Confectionery/FormSell.cs +++ b/Confectionery/Confectionery/FormSell.cs @@ -52,7 +52,7 @@ namespace Confectionery bool operationResult = _logicS.Sell(Convert.ToInt32(comboBoxPastry.SelectedValue), count); if (!operationResult) { - throw new Exception("Ошибка при создании поставки. Дополнительная информация в логах."); + throw new Exception("Ошибка при создании списания. Дополнительная информация в логах."); } MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); DialogResult = DialogResult.OK; diff --git a/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs b/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs index 214c74f..d37aa1b 100644 --- a/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs +++ b/Confectionery/ConfectioneryFileImplements/Implements/ShopStorage.cs @@ -115,15 +115,14 @@ namespace ConfectioneryFileImplement.Implements } else { - int dif = count - freeShopSpace; count -= freeShopSpace; if (shop.Pastries.TryGetValue(pastryId, out var pastryCount)) { - shop.Pastries[pastryId] = pastryCount + count; + shop.Pastries[pastryId] = pastryCount + freeShopSpace; } else { - shop.Pastries.Add(pastryId, count); + shop.Pastries.Add(pastryId, freeShopSpace); } shop.setShopPastriesNull(); } -- 2.25.1