From 09aa0a21051d13817a0d346b937d8cad78ef54be Mon Sep 17 00:00:00 2001 From: "yuliya.mavrina@internet.ru" Date: Tue, 5 Mar 2024 22:30:33 +0300 Subject: [PATCH 1/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=5F2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RenovationWork/RenovationWork.sln | 16 +++- RenovationWork/RenovationWork/Program.cs | 6 +- .../RenovationWork/RenovationWorkView.csproj | 1 + .../DataFileSingleton.cs | 63 ++++++++++++ .../Implements/ComponentStorage.cs | 93 ++++++++++++++++++ .../Implements/OrderStorage.cs | 96 +++++++++++++++++++ .../Implements/RepairStorage.cs | 90 +++++++++++++++++ .../Models/Component.cs | 69 +++++++++++++ .../Models/Order.cs | 87 +++++++++++++++++ .../Models/Repair.cs | 89 +++++++++++++++++ .../RenovationWorkFileImplement.csproj | 14 +++ 11 files changed, 618 insertions(+), 6 deletions(-) create mode 100644 RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs create mode 100644 RenovationWork/RenovationWorkFileImplement/Implements/ComponentStorage.cs create mode 100644 RenovationWork/RenovationWorkFileImplement/Implements/OrderStorage.cs create mode 100644 RenovationWork/RenovationWorkFileImplement/Implements/RepairStorage.cs create mode 100644 RenovationWork/RenovationWorkFileImplement/Models/Component.cs create mode 100644 RenovationWork/RenovationWorkFileImplement/Models/Order.cs create mode 100644 RenovationWork/RenovationWorkFileImplement/Models/Repair.cs create mode 100644 RenovationWork/RenovationWorkFileImplement/RenovationWorkFileImplement.csproj diff --git a/RenovationWork/RenovationWork.sln b/RenovationWork/RenovationWork.sln index 5b85026..03fbac7 100644 --- a/RenovationWork/RenovationWork.sln +++ b/RenovationWork/RenovationWork.sln @@ -3,15 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.7.34024.191 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenovationWorkView", "RenovationWork\RenovationWorkView.csproj", "{F7DA64D8-ACE1-4703-906A-A25CBD36F7BE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenovationWorkView", "RenovationWork\RenovationWorkView.csproj", "{F7DA64D8-ACE1-4703-906A-A25CBD36F7BE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenovationWorkDataModels", "RenovationWorkDataModels\RenovationWorkDataModels.csproj", "{7B3260AB-0375-4F6A-A1E1-E74228E20DAA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenovationWorkDataModels", "RenovationWorkDataModels\RenovationWorkDataModels.csproj", "{7B3260AB-0375-4F6A-A1E1-E74228E20DAA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenovationWorkContracts", "RenovationWorkContracts\RenovationWorkContracts.csproj", "{933A8F36-3513-48F4-848A-635597FDFE1C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenovationWorkContracts", "RenovationWorkContracts\RenovationWorkContracts.csproj", "{933A8F36-3513-48F4-848A-635597FDFE1C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenovationWorkBusinessLogic", "RenovationWorkBusinessLogic\RenovationWorkBusinessLogic.csproj", "{F7FB3E21-1E5E-4271-A22B-53B0E40E1F95}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenovationWorkBusinessLogic", "RenovationWorkBusinessLogic\RenovationWorkBusinessLogic.csproj", "{F7FB3E21-1E5E-4271-A22B-53B0E40E1F95}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenovationWorkListImplement", "RenovationWorkListImplement\RenovationWorkListImplement.csproj", "{5F454425-8555-4E69-A0EC-0EEC94309A06}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenovationWorkListImplement", "RenovationWorkListImplement\RenovationWorkListImplement.csproj", "{5F454425-8555-4E69-A0EC-0EEC94309A06}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenovationWorkFileImplement", "RenovationWorkFileImplement\RenovationWorkFileImplement.csproj", "{F50D3080-2C2A-4189-AECA-11FA748D9C6E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -39,6 +41,10 @@ Global {5F454425-8555-4E69-A0EC-0EEC94309A06}.Debug|Any CPU.Build.0 = Debug|Any CPU {5F454425-8555-4E69-A0EC-0EEC94309A06}.Release|Any CPU.ActiveCfg = Release|Any CPU {5F454425-8555-4E69-A0EC-0EEC94309A06}.Release|Any CPU.Build.0 = Release|Any CPU + {F50D3080-2C2A-4189-AECA-11FA748D9C6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F50D3080-2C2A-4189-AECA-11FA748D9C6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F50D3080-2C2A-4189-AECA-11FA748D9C6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F50D3080-2C2A-4189-AECA-11FA748D9C6E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/RenovationWork/RenovationWork/Program.cs b/RenovationWork/RenovationWork/Program.cs index 419c2af..c90ed8a 100644 --- a/RenovationWork/RenovationWork/Program.cs +++ b/RenovationWork/RenovationWork/Program.cs @@ -1,17 +1,21 @@ using RenovationWorkBusinessLogic.BusinessLogics; using RenovationWorkContracts.BusinessLogicsContracts; using RenovationWorkContracts.StoragesContracts; -using RenovationWorkListImplement.Implements; +using RenovationWorkFileImplement.Implements; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NLog.Extensions.Logging; + namespace RenovationWorkView { internal static class Program { private static ServiceProvider? _serviceProvider; public static ServiceProvider? ServiceProvider => _serviceProvider; + /// + /// The main entry point for the application. + /// [STAThread] static void Main() { diff --git a/RenovationWork/RenovationWork/RenovationWorkView.csproj b/RenovationWork/RenovationWork/RenovationWorkView.csproj index f6aa5a9..9816f97 100644 --- a/RenovationWork/RenovationWork/RenovationWorkView.csproj +++ b/RenovationWork/RenovationWork/RenovationWorkView.csproj @@ -19,6 +19,7 @@ + diff --git a/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs b/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs new file mode 100644 index 0000000..687b0be --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using RenovationWorkFileImplement.Models; + + +namespace RenovationWorkFileImplement +{ + internal class DataFileSingleton + { + private static DataFileSingleton? instance; + private readonly string ComponentFileName = "Component.xml"; + private readonly string OrderFileName = "Order.xml"; + private readonly string RepairFileName = "Repair.xml"; + public List Components { get; private set; } + public List Orders { get; private set; } + public List Repairs { get; private set; } + + public static DataFileSingleton GetInstance() + { + if (instance == null) + { + instance = new DataFileSingleton(); + } + return instance; + } + + public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); + public void SaveRepairs() => SaveData(Repairs, RepairFileName, "Repairs", x => x.GetXElement); + public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + private DataFileSingleton() + { + Components = LoadData(ComponentFileName, "Component", x => + Component.Create(x)!)!; + Repairs = LoadData(RepairFileName, "Repair", x => + Repair.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); + } + } + + + } +} \ No newline at end of file diff --git a/RenovationWork/RenovationWorkFileImplement/Implements/ComponentStorage.cs b/RenovationWork/RenovationWorkFileImplement/Implements/ComponentStorage.cs new file mode 100644 index 0000000..ca8fd6b --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/Implements/ComponentStorage.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RenovationWorkContracts.BindingModels; +using RenovationWorkContracts.SearchModels; +using RenovationWorkContracts.StoragesContracts; +using RenovationWorkContracts.ViewModels; +using RenovationWorkFileImplement.Models; + +namespace RenovationWorkFileImplement.Implements +{ + public class ComponentStorage : IComponentStorage + { + private readonly DataFileSingleton source; + public ComponentStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Components + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ComponentSearchModel + model) + { + if (string.IsNullOrEmpty(model.ComponentName)) + { + return new(); + } + return source.Components + .Where(x => x.ComponentName.Contains(model.ComponentName)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public ComponentViewModel? GetElement(ComponentSearchModel model) + { + if (string.IsNullOrEmpty(model.ComponentName) && !model.Id.HasValue) + { + return null; + } + + //чтобы получить первый элемент, который удовлетворяет заданным условиям выборки + return source.Components + .FirstOrDefault(x => + (!string.IsNullOrEmpty(model.ComponentName) && x.ComponentName == + model.ComponentName) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; //вызывается для найденного элемента вернуть представление модели ComponentViewModel + } + public ComponentViewModel? Insert(ComponentBindingModel model) + { + model.Id = source.Components.Count > 0 ? source.Components.Max(x => + x.Id) + 1 : 1; + var newComponent = Component.Create(model); + if (newComponent == null) + { + return null; + } + source.Components.Add(newComponent); + source.SaveComponents(); + return newComponent.GetViewModel; + } + public ComponentViewModel? Update(ComponentBindingModel model) + { + var component = source.Components.FirstOrDefault(x => x.Id == + model.Id); + if (component == null) + { + return null; + } + component.Update(model); + source.SaveComponents(); + return component.GetViewModel; + } + public ComponentViewModel? Delete(ComponentBindingModel model) + { + var element = source.Components.FirstOrDefault(x => x.Id == + model.Id); + if (element != null) + { + source.Components.Remove(element); + source.SaveComponents(); + return element.GetViewModel; + } + return null; + } + } +} \ No newline at end of file diff --git a/RenovationWork/RenovationWorkFileImplement/Implements/OrderStorage.cs b/RenovationWork/RenovationWorkFileImplement/Implements/OrderStorage.cs new file mode 100644 index 0000000..586c135 --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/Implements/OrderStorage.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RenovationWorkContracts.BindingModels; +using RenovationWorkContracts.SearchModels; +using RenovationWorkContracts.StoragesContracts; +using RenovationWorkContracts.ViewModels; +using RenovationWorkFileImplement.Models; + +namespace RenovationWorkFileImplement.Implements +{ + public class OrderStorage : IOrderStorage + { + private readonly DataFileSingleton source; + public OrderStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Orders.Select(x => AccessRepairStorage(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 => AccessRepairStorage(x.GetViewModel)) + .ToList(); + } + public OrderViewModel? GetElement(OrderSearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + return AccessRepairStorage(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 AccessRepairStorage(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 AccessRepairStorage(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 AccessRepairStorage(element.GetViewModel); + } + return null; + } + public OrderViewModel? AccessRepairStorage(OrderViewModel model) + { + if (model == null) + return null; + foreach (var Repair in source.Repairs) + { + if (Repair.Id == model.RepairId) + { + model.RepairName = Repair.RepairName; + break; + } + } + return model; + } + } +} + diff --git a/RenovationWork/RenovationWorkFileImplement/Implements/RepairStorage.cs b/RenovationWork/RenovationWorkFileImplement/Implements/RepairStorage.cs new file mode 100644 index 0000000..d147d72 --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/Implements/RepairStorage.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RenovationWorkContracts.BindingModels; +using RenovationWorkContracts.SearchModels; +using RenovationWorkContracts.StoragesContracts; +using RenovationWorkContracts.ViewModels; +using RenovationWorkFileImplement.Models; +namespace RenovationWorkFileImplement.Implements +{ + public class RepairStorage : IRepairStorage + { + private readonly DataFileSingleton source; + public RepairStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Repairs + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(RepairSearchModel model) + { + if (string.IsNullOrEmpty(model.RepairName)) + { + return new(); + } + return source.Repairs + .Where(x => x.RepairName.Contains(model.RepairName)) + .Select(x => x.GetViewModel) + .ToList(); + } + public RepairViewModel? GetElement(RepairSearchModel model) + { + if (string.IsNullOrEmpty(model.RepairName) && !model.Id.HasValue) + { + return null; + } + return source.Repairs + .FirstOrDefault(x => + (!string.IsNullOrEmpty(model.RepairName) && x.RepairName == + model.RepairName) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + public RepairViewModel? Insert(RepairBindingModel model) + { + model.Id = source.Repairs.Count > 0 ? source.Repairs.Max(x => + x.Id) + 1 : 1; + var newRepair = Repair.Create(model); + if (newRepair == null) + { + return null; + } + source.Repairs.Add(newRepair); + source.SaveRepairs(); + return newRepair.GetViewModel; + } + public RepairViewModel? Update(RepairBindingModel model) + { + var Repair = source.Repairs.FirstOrDefault(x => x.Id == + model.Id); + if (Repair == null) + { + return null; + } + Repair.Update(model); + source.SaveRepairs(); + return Repair.GetViewModel; + } + public RepairViewModel? Delete(RepairBindingModel model) + { + var Repair = source.Repairs.FirstOrDefault(x => x.Id == + model.Id); + if (Repair != null) + { + source.Repairs.Remove(Repair); + source.SaveRepairs(); + return Repair.GetViewModel; + } + return null; + } + } +} + diff --git a/RenovationWork/RenovationWorkFileImplement/Models/Component.cs b/RenovationWork/RenovationWorkFileImplement/Models/Component.cs new file mode 100644 index 0000000..da4a7d6 --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/Models/Component.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RenovationWorkContracts.BindingModels; +using RenovationWorkContracts.ViewModels; +using RenovationWorkDataModels.Models; +using System.Xml.Linq; + +namespace RenovationWorkFileImplement.Models +{ + public class Component : IComponentModel + { + public int Id { get; set; } + public string ComponentName { get; set; } = string.Empty; + public double Cost { get; set; } + + public static Component? Create(ComponentBindingModel model) + { + if (model == null) + { + return null; + } + return new Component() + { + Id = model.Id, + ComponentName = model.ComponentName, + Cost = model.Cost, + }; + } + + public static Component? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Component() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ComponentName = element.Element("ComponentName")!.Value, + Cost = Convert.ToDouble(element.Element("Cost")!.Value), + }; + } + + public void Update(ComponentBindingModel model) + { + if (model == null) + { + return; + } + ComponentName = model.ComponentName; + Cost = model.Cost; + } + + public ComponentViewModel GetViewModel => new() + { + Id = Id, + ComponentName = ComponentName, + Cost = Cost + }; + + public XElement GetXElement => new("Component", + new XAttribute("Id", Id), + new XElement("ComponentName", ComponentName), + new XElement("Cost", Cost.ToString())); + } +} diff --git a/RenovationWork/RenovationWorkFileImplement/Models/Order.cs b/RenovationWork/RenovationWorkFileImplement/Models/Order.cs new file mode 100644 index 0000000..788d640 --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/Models/Order.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RenovationWorkContracts.BindingModels; +using RenovationWorkContracts.ViewModels; +using RenovationWorkDataModels.Enums; +using RenovationWorkDataModels.Models; +using System.Xml.Linq; + +namespace RenovationWorkFileImplement.Models +{ + public class Order : IOrderModel + { + public int Id { get; private set; } + public int RepairId { 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, + RepairId = model.RepairId, + 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), + RepairId = Convert.ToInt32(element.Element("RepairId")!.Value), + Count = Convert.ToInt32(element.Element("Count")!.Value), + Sum = Convert.ToDouble(element.Element("Sum")!.Value), + Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value.ToString()), + DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value), + DateImplement = string.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null : Convert.ToDateTime(element.Element("DateImplement")!.Value) + }; + } + public void Update(OrderBindingModel model) + { + if (model == null) + { + return; + } + Status = model.Status; + DateImplement = model.DateImplement; + } + public OrderViewModel GetViewModel => new() + { + Id = Id, + RepairId = RepairId, + Count = Count, + Sum = Sum, + Status = Status, + DateCreate = DateCreate, + DateImplement = DateImplement, + }; + public XElement GetXElement => new("Order", + new XAttribute("Id", Id), + new XElement("RepairId", RepairId), + new XElement("Sum", Sum.ToString()), + new XElement("Count", Count), + new XElement("Status", Status.ToString()), + new XElement("DateCreate", DateCreate.ToString()), + new XElement("DateImplement", DateImplement.ToString()) + ); + } +} \ No newline at end of file diff --git a/RenovationWork/RenovationWorkFileImplement/Models/Repair.cs b/RenovationWork/RenovationWorkFileImplement/Models/Repair.cs new file mode 100644 index 0000000..4ad86d7 --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/Models/Repair.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RenovationWorkContracts.BindingModels; +using RenovationWorkContracts.ViewModels; +using RenovationWorkDataModels.Models; +using System.Xml.Linq; + +namespace RenovationWorkFileImplement.Models +{ + public class Repair : IRepairModel + { + public int Id { get; private set; } + public string RepairName { get; private set; } = string.Empty; + public double Price { get; private set; } + public Dictionary Components { get; private set; } = new(); + private Dictionary? _repairComponents = null; + public Dictionary RepairComponents + { + get + { + if (_repairComponents == null) + { + var source = DataFileSingleton.GetInstance(); + _repairComponents = Components.ToDictionary(x => x.Key, y => + ((source.Components.FirstOrDefault(z => z.Id == y.Key) as IComponentModel)!, y.Value)); + } + return _repairComponents; + } + } + public static Repair? Create(RepairBindingModel model) + { + if (model == null) + { + return null; + } + return new Repair() + { + Id = model.Id, + RepairName = model.RepairName, + Price = model.Price, + Components = model.RepairComponents.ToDictionary(x => x.Key, x => x.Value.Item2) + }; + } + public static Repair? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Repair() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + RepairName = element.Element("RepairName")!.Value, + Price = Convert.ToDouble(element.Element("Price")!.Value), + Components = element.Element("RepairComponents")!.Elements("RepairComponent").ToDictionary(x => + Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value)) + }; + } + public void Update(RepairBindingModel model) + { + if (model == null) + { + return; + } + RepairName = model.RepairName; + Price = model.Price; + Components = model.RepairComponents.ToDictionary(x => x.Key, x => x.Value.Item2); + _repairComponents = null; + } + public RepairViewModel GetViewModel => new() + { + Id = Id, + RepairName = RepairName, + Price = Price, + RepairComponents = RepairComponents + }; + public XElement GetXElement => new("Repair", + new XAttribute("Id", Id), + new XElement("RepairName", RepairName), + new XElement("Price", Price.ToString()), + new XElement("RepairComponents", Components.Select(x => + new XElement("RepairComponent", + new XElement("Key", x.Key), + new XElement("Value", x.Value))).ToArray())); + } +} diff --git a/RenovationWork/RenovationWorkFileImplement/RenovationWorkFileImplement.csproj b/RenovationWork/RenovationWorkFileImplement/RenovationWorkFileImplement.csproj new file mode 100644 index 0000000..2d896a8 --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/RenovationWorkFileImplement.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + -- 2.25.1 From 21a3fe7c630d9344b68badb9269b8d5a38ef531f Mon Sep 17 00:00:00 2001 From: "yuliya.mavrina@internet.ru" Date: Sat, 30 Mar 2024 20:02:35 +0300 Subject: [PATCH 2/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=5F2=5F=D1=81=D0=BB=D0=BE=D0=B6?= =?UTF-8?q?=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RenovationWork/FormMain.Designer.cs | 11 +- RenovationWork/RenovationWork/FormMain.cs | 9 ++ .../RenovationWork/FormSell.Designer.cs | 118 ++++++++++++++++ RenovationWork/RenovationWork/FormSell.cs | 116 ++++++++++++++++ RenovationWork/RenovationWork/FormSell.resx | 120 ++++++++++++++++ .../RenovationWork/FormShop.Designer.cs | 28 +++- RenovationWork/RenovationWork/FormShop.cs | 5 +- RenovationWork/RenovationWork/FormSupply.cs | 2 +- RenovationWork/RenovationWork/Program.cs | 1 + .../BusinessLogics/OrderLogic.cs | 106 +++++++++++--- .../BusinessLogics/ShopLogic.cs | 91 +++++++----- .../BindingModels/ShopBindingModel.cs | 1 + .../BusinessLogicsContracts/IShopLogic.cs | 1 + .../StoragesContracts/IShopStorage.cs | 2 + .../ViewModels/ShopViewModel.cs | 2 + .../Models/IShopModel.cs | 1 + .../DataFileSingleton.cs | 6 +- .../Implements/ShopStorage.cs | 129 ++++++++++++++++++ .../Models/Shop.cs | 107 +++++++++++++++ .../Implements/ShopStorage.cs | 5 + .../Models/Shop.cs | 1 + 21 files changed, 802 insertions(+), 60 deletions(-) create mode 100644 RenovationWork/RenovationWork/FormSell.Designer.cs create mode 100644 RenovationWork/RenovationWork/FormSell.cs create mode 100644 RenovationWork/RenovationWork/FormSell.resx create mode 100644 RenovationWork/RenovationWorkFileImplement/Implements/ShopStorage.cs create mode 100644 RenovationWork/RenovationWorkFileImplement/Models/Shop.cs diff --git a/RenovationWork/RenovationWork/FormMain.Designer.cs b/RenovationWork/RenovationWork/FormMain.Designer.cs index 08bd3d0..9987d1f 100644 --- a/RenovationWork/RenovationWork/FormMain.Designer.cs +++ b/RenovationWork/RenovationWork/FormMain.Designer.cs @@ -40,6 +40,7 @@ buttonOrderReady = new Button(); buttonIssuedOrder = new Button(); buttonRef = new Button(); + SalesToolStripMenuItem = new ToolStripMenuItem(); menuStrip.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); SuspendLayout(); @@ -55,7 +56,7 @@ // // refbooksToolStripMenuItem // - refbooksToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { componentsToolStripMenuItem, JobTypeToolStripMenuItem, ShopsToolStripMenuItem, SupplyToolStripMenuItem }); + refbooksToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { componentsToolStripMenuItem, JobTypeToolStripMenuItem, ShopsToolStripMenuItem, SupplyToolStripMenuItem, SalesToolStripMenuItem }); refbooksToolStripMenuItem.Name = "refbooksToolStripMenuItem"; refbooksToolStripMenuItem.Size = new Size(94, 20); refbooksToolStripMenuItem.Text = "Справочники"; @@ -148,6 +149,13 @@ buttonRef.UseVisualStyleBackColor = true; buttonRef.Click += buttonRef_Click; // + // SalesToolStripMenuItem + // + SalesToolStripMenuItem.Name = "SalesToolStripMenuItem"; + SalesToolStripMenuItem.Size = new Size(198, 22); + SalesToolStripMenuItem.Text = "Продажи"; + SalesToolStripMenuItem.Click += SalesToolStripMenuItem_Click; + // // FormMain // AutoScaleDimensions = new SizeF(7F, 15F); @@ -185,5 +193,6 @@ private Button buttonRef; private ToolStripMenuItem ShopsToolStripMenuItem; private ToolStripMenuItem SupplyToolStripMenuItem; + private ToolStripMenuItem SalesToolStripMenuItem; } } \ No newline at end of file diff --git a/RenovationWork/RenovationWork/FormMain.cs b/RenovationWork/RenovationWork/FormMain.cs index 22b2ef0..24293da 100644 --- a/RenovationWork/RenovationWork/FormMain.cs +++ b/RenovationWork/RenovationWork/FormMain.cs @@ -172,6 +172,15 @@ namespace RenovationWorkView form.ShowDialog(); } } + + private void SalesToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormSell)); + if (service is FormSell form) + { + form.ShowDialog(); + } + } } } diff --git a/RenovationWork/RenovationWork/FormSell.Designer.cs b/RenovationWork/RenovationWork/FormSell.Designer.cs new file mode 100644 index 0000000..4d8eb05 --- /dev/null +++ b/RenovationWork/RenovationWork/FormSell.Designer.cs @@ -0,0 +1,118 @@ +namespace RenovationWorkView +{ + 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() + { + buttonSave = new Button(); + buttonCancel = new Button(); + labelRepair = new Label(); + labelCount = new Label(); + textBoxCount = new TextBox(); + comboBoxRepair = new ComboBox(); + SuspendLayout(); + // + // buttonSave + // + buttonSave.Location = new Point(233, 74); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(75, 23); + buttonSave.TabIndex = 0; + buttonSave.Text = "Сохранить"; + buttonSave.UseVisualStyleBackColor = true; + buttonSave.Click += buttonSave_Click; + // + // buttonCancel + // + buttonCancel.Location = new Point(314, 74); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new Size(75, 23); + buttonCancel.TabIndex = 1; + buttonCancel.Text = "Отмена"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += buttonCancel_Click; + // + // labelRepair + // + labelRepair.AutoSize = true; + labelRepair.Location = new Point(12, 9); + labelRepair.Name = "labelRepair"; + labelRepair.Size = new Size(56, 15); + labelRepair.TabIndex = 2; + labelRepair.Text = "Изделие:"; + // + // labelCount + // + labelCount.AutoSize = true; + labelCount.Location = new Point(12, 46); + labelCount.Name = "labelCount"; + labelCount.Size = new Size(75, 15); + labelCount.TabIndex = 3; + labelCount.Text = "Количество:"; + // + // textBoxCount + // + textBoxCount.Location = new Point(100, 38); + textBoxCount.Name = "textBoxCount"; + textBoxCount.Size = new Size(107, 23); + textBoxCount.TabIndex = 4; + // + // comboBoxRepair + // + comboBoxRepair.FormattingEnabled = true; + comboBoxRepair.Location = new Point(100, 6); + comboBoxRepair.Name = "comboBoxRepair"; + comboBoxRepair.Size = new Size(289, 23); + comboBoxRepair.TabIndex = 5; + // + // FormSell + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(401, 109); + Controls.Add(comboBoxRepair); + Controls.Add(textBoxCount); + Controls.Add(labelCount); + Controls.Add(labelRepair); + Controls.Add(buttonCancel); + Controls.Add(buttonSave); + Name = "FormSell"; + Text = "Продажи"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Button buttonSave; + private Button buttonCancel; + private Label labelRepair; + private Label labelCount; + private TextBox textBoxCount; + private ComboBox comboBoxRepair; + } +} \ No newline at end of file diff --git a/RenovationWork/RenovationWork/FormSell.cs b/RenovationWork/RenovationWork/FormSell.cs new file mode 100644 index 0000000..df6d478 --- /dev/null +++ b/RenovationWork/RenovationWork/FormSell.cs @@ -0,0 +1,116 @@ +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; +using RenovationWorkContracts.ViewModels; +using RenovationWorkDataModels.Models; +using Microsoft.Extensions.Logging; +using RenovationWorkContracts.BusinessLogicsContracts; +using RenovationWorkBusinessLogic.BusinessLogics; + +namespace RenovationWorkView +{ + public partial class FormSell : Form + { + private readonly List? _repairList; + IShopLogic _shopLogic; + IRepairLogic _repairLogic; + public FormSell(IRepairLogic repairLogic, IShopLogic shopLogic) + { + InitializeComponent(); + _shopLogic = shopLogic; + _repairLogic = repairLogic; + _repairList = repairLogic.ReadList(null); + if (_repairList != null) + { + comboBoxRepair.DisplayMember = "RepairName"; + comboBoxRepair.ValueMember = "Id"; + comboBoxRepair.DataSource = _repairList; + comboBoxRepair.SelectedItem = null; + } + } + public int RepairId + { + get + { + return Convert.ToInt32(comboBoxRepair.SelectedValue); + } + set + { + comboBoxRepair.SelectedValue = value; + } + } + public IRepairModel? RepairModel + { + get + { + if (_repairList == null) + { + return null; + } + foreach (var elem in _repairList) + { + if (elem.Id == RepairId) + { + return elem; + } + } + return null; + } + } + public int Count + { + get { return Convert.ToInt32(textBoxCount.Text); } + set + { textBoxCount.Text = value.ToString(); } + } + + private void buttonSave_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(textBoxCount.Text)) + { + MessageBox.Show("Заполните поле Количество", "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (comboBoxRepair.SelectedValue == null) + { + MessageBox.Show("Выберите изделие", "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + try + { + int count = Convert.ToInt32(textBoxCount.Text); + var manufacture = _repairLogic.ReadElement(new() { Id = Convert.ToInt32(comboBoxRepair.SelectedValue) }); + if (manufacture == null) + { + throw new ApplicationException("Ошибка при продаже. Ошибка получения данных об элементе."); + } + if (!_shopLogic.SellRepairs(manufacture, count)) + { + throw new ApplicationException("Ошибка при продаже. Недостаточно изделий данного типа в магазинах."); + } + MessageBox.Show("Продажа прошла успешно"); + DialogResult = DialogResult.OK; + Close(); + } + catch (Exception) + { + MessageBox.Show("Ошибка при продаже."); + return; + } + } + + private void buttonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/RenovationWork/RenovationWork/FormSell.resx b/RenovationWork/RenovationWork/FormSell.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/RenovationWork/RenovationWork/FormSell.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/RenovationWork/RenovationWork/FormShop.Designer.cs b/RenovationWork/RenovationWork/FormShop.Designer.cs index e41cc84..616aaf3 100644 --- a/RenovationWork/RenovationWork/FormShop.Designer.cs +++ b/RenovationWork/RenovationWork/FormShop.Designer.cs @@ -41,7 +41,10 @@ ColumnCount = new DataGridViewTextBoxColumn(); buttonSave = new Button(); buttonCancel = new Button(); + labelCapancy = new Label(); + CapacityUpDown = new NumericUpDown(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); + ((System.ComponentModel.ISupportInitialize)CapacityUpDown).BeginInit(); SuspendLayout(); // // labelName @@ -96,10 +99,10 @@ // dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; dataGridView.Columns.AddRange(new DataGridViewColumn[] { ColumnId, ColumnName, ColumnPrice, ColumnCount }); - dataGridView.Location = new Point(12, 108); + dataGridView.Location = new Point(12, 126); dataGridView.Name = "dataGridView"; dataGridView.RowTemplate.Height = 25; - dataGridView.Size = new Size(770, 250); + dataGridView.Size = new Size(770, 232); dataGridView.TabIndex = 6; // // ColumnId @@ -149,11 +152,29 @@ buttonCancel.UseVisualStyleBackColor = true; buttonCancel.Click += buttonCancel_Click; // + // labelCapancy + // + labelCapancy.AutoSize = true; + labelCapancy.Location = new Point(12, 99); + labelCapancy.Name = "labelCapancy"; + labelCapancy.Size = new Size(83, 15); + labelCapancy.TabIndex = 9; + labelCapancy.Text = "Вместимость:"; + // + // CapacityUpDown + // + CapacityUpDown.Location = new Point(106, 97); + CapacityUpDown.Name = "CapacityUpDown"; + CapacityUpDown.Size = new Size(229, 23); + CapacityUpDown.TabIndex = 10; + // // FormShop // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(790, 411); + Controls.Add(CapacityUpDown); + Controls.Add(labelCapancy); Controls.Add(buttonCancel); Controls.Add(buttonSave); Controls.Add(dataGridView); @@ -167,6 +188,7 @@ Text = "Магазин"; Load += FormShop_Load; ((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); + ((System.ComponentModel.ISupportInitialize)CapacityUpDown).EndInit(); ResumeLayout(false); PerformLayout(); } @@ -186,5 +208,7 @@ private DataGridViewTextBoxColumn ColumnCount; private Button buttonSave; private Button buttonCancel; + private Label labelCapancy; + private NumericUpDown CapacityUpDown; } } \ No newline at end of file diff --git a/RenovationWork/RenovationWork/FormShop.cs b/RenovationWork/RenovationWork/FormShop.cs index de327df..53c2cfd 100644 --- a/RenovationWork/RenovationWork/FormShop.cs +++ b/RenovationWork/RenovationWork/FormShop.cs @@ -45,7 +45,8 @@ namespace RenovationWorkView textBoxName.Text = shop.ShopName; textBoxAddress.Text = shop.Address; dateTimePicker.Text = shop.OpeningDate.ToString(); - _repairs = shop.ShopRepairs; + _repairs = shop.ShopRepairs ?? new Dictionary(); + CapacityUpDown.Value = shop.MaxCapacity; } LoadData(); } @@ -101,7 +102,7 @@ namespace RenovationWorkView ShopName = textBoxName.Text, Address = textBoxAddress.Text, OpeningDate = dateTimePicker.Value.Date, - ShopRepairs = _repairs + MaxCapacity = Convert.ToInt32(CapacityUpDown.Value) }; var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model); if (!operationResult) diff --git a/RenovationWork/RenovationWork/FormSupply.cs b/RenovationWork/RenovationWork/FormSupply.cs index 723394b..2473bb3 100644 --- a/RenovationWork/RenovationWork/FormSupply.cs +++ b/RenovationWork/RenovationWork/FormSupply.cs @@ -100,7 +100,7 @@ namespace RenovationWorkView } if (comboBoxRepair.SelectedValue == null) { - MessageBox.Show("Выберите кузнечное изделие", "Ошибка", + MessageBox.Show("Выберите ремонтное изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } diff --git a/RenovationWork/RenovationWork/Program.cs b/RenovationWork/RenovationWork/Program.cs index d6149c9..2d0079c 100644 --- a/RenovationWork/RenovationWork/Program.cs +++ b/RenovationWork/RenovationWork/Program.cs @@ -52,6 +52,7 @@ namespace RenovationWorkView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file diff --git a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs index b34651d..b09d8a2 100644 --- a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs @@ -9,6 +9,7 @@ using RenovationWorkContracts.SearchModels; using RenovationWorkContracts.StoragesContracts; using RenovationWorkContracts.ViewModels; using RenovationWorkDataModels.Enums; +using RenovationWorkDataModels.Models; using Microsoft.Extensions.Logging; namespace RenovationWorkBusinessLogic.BusinessLogics @@ -17,10 +18,17 @@ namespace RenovationWorkBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + private readonly IShopLogic _shopLogic; + private readonly IRepairStorage _repairStorage; + private readonly IShopStorage _shopStorage; + public OrderLogic(ILogger logger, IOrderStorage orderStorage, + IRepairStorage repairStorage, IShopLogic shopLogic, IShopStorage shopStorage) { _logger = logger; _orderStorage = orderStorage; + _repairStorage = repairStorage; + _shopLogic = shopLogic; + _shopStorage = shopStorage; } public bool CreateOrder(OrderBindingModel model) { @@ -39,31 +47,38 @@ namespace RenovationWorkBusinessLogic.BusinessLogics } return true; } - public bool StatusUpdate(OrderBindingModel model, OrderStatus newStatus) + private bool StatusUpdate(OrderBindingModel model, OrderStatus status) { - var viewModel = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); - if (viewModel == null) + CheckModel(model); + var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); + if (element == null) { - throw new ArgumentNullException(nameof(model)); - } - if (viewModel.Status + 1 != newStatus) - { - _logger.LogWarning("Update operation failed. Order status incorrect."); + _logger.LogWarning("Read operation failed"); return false; } - model.Status = newStatus; - if (model.Status == OrderStatus.Готов) model.DateImplement = DateTime.Now; - else + if (element.Status != status - 1) { - model.DateImplement = viewModel.DateImplement; + _logger.LogWarning("Status change operation failed"); + throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный"); } - CheckModel(model, false); - if (_orderStorage.Update(model) == null) + if (element.Status == OrderStatus.Готов) { - model.Status--; - _logger.LogWarning("Update operation failed"); - return false; + var manufacture = _repairStorage.GetElement(new RepairSearchModel() { Id = model.RepairId }); + if (manufacture == null) + { + _logger.LogWarning("Status update to " + status.ToString() + " operation failed. Document not found."); + return false; + } + if (CheckSupply(manufacture, model.Count) == false) + { + _logger.LogWarning("Status update to " + status.ToString() + " operation failed. Shop supply error."); + return false; + } } + model.Status = status; + if (model.Status == OrderStatus.Выдан) + model.DateImplement = DateTime.Now; + _orderStorage.Update(model); return true; } public bool DeliveryOrder(OrderBindingModel model) @@ -115,5 +130,60 @@ namespace RenovationWorkBusinessLogic.BusinessLogics } _logger.LogInformation("Order. Count: {Count}. Sum: {Sum}. Id: {Id}", model.Count, model.Sum, model.Id); } + private bool CheckSupply(IRepairModel repair, int count) + { + if (count <= 0) + { + _logger.LogWarning("Check then supply operation error. Repair count < 0."); + return false; + } + int sumCapacity = 0; + int sumCount = 0; + sumCapacity = _shopStorage.GetFullList().Select(x => x.MaxCapacity).Sum(); + sumCount = _shopStorage.GetFullList().Select(x => x.ShopRepairs.Select(y => y.Value.Item2).Sum()).Sum(); + int freeSpace = sumCapacity - sumCount; + if (freeSpace - count < 0) + { + _logger.LogWarning("Check then supply operation error. There's no place for new Repair in shops."); + return false; + } + foreach (var shop in _shopStorage.GetFullList()) + { + freeSpace = shop.MaxCapacity; + foreach (var doc in shop.ShopRepairs) + { + freeSpace -= doc.Value.Item2; + } + if (freeSpace == 0) + { + continue; + } + if (freeSpace - count >= 0) + { + if (_shopLogic.ReplenishRepairs(new() { Id = shop.Id }, repair, count)) + count = 0; + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + if (freeSpace - count < 0) + { + if (_shopLogic.ReplenishRepairs(new() { Id = shop.Id }, repair, freeSpace)) + count -= freeSpace; + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + if (count <= 0) + { + return true; + } + } + return false; + } } } \ No newline at end of file diff --git a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/ShopLogic.cs b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/ShopLogic.cs index 7e3960a..53ffe56 100644 --- a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/ShopLogic.cs +++ b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/ShopLogic.cs @@ -84,44 +84,61 @@ namespace RenovationWorkBusinessLogic.BusinessLogics } public bool ReplenishRepairs(ShopSearchModel model, IRepairModel repair, int count) { - _logger.LogInformation("Try to replenish repairs. ShopName:{ShopName}. Id:{Id}", model.ShopName, model.Id); - if (model == null) - throw new ArgumentNullException(nameof(model)); - ShopViewModel? curModel = ReadElement(model); - if (curModel == null) { - _logger.LogWarning("Read operation failed"); - return false; + _logger.LogInformation("Try to replenish repairs. ShopName:{ShopName}. Id:{Id}", model.ShopName, model.Id); + if (model == null) + { + _logger.LogWarning("Read operation failed"); + throw new ArgumentNullException(nameof(model)); + } + ShopViewModel? curModel = ReadElement(model); + if (curModel == null) + { + _logger.LogWarning("Read operation failed"); + throw new ArgumentNullException(nameof(curModel)); + } + if (repair == null) + { + _logger.LogWarning("Read operation failed"); + throw new ArgumentNullException(nameof(repair)); + } + if (count <= 0) + { + _logger.LogWarning("Read operation failed"); + throw new ArgumentException("Количество должно быть положительным"); + } + int countItems = curModel.ShopRepairs.Select(x => x.Value.Item2).Sum(); + if (curModel.MaxCapacity - countItems >= count) + { + if (curModel.ShopRepairs.TryGetValue(repair.Id, out var sameDocument)) + { + curModel.ShopRepairs[repair.Id] = (repair, sameDocument.Item2 + count); + _logger.LogInformation("Same repair found by supply. Added {0} of {1} in {2} shop", count, repair.RepairName, curModel.ShopName); + } + else + { + curModel.ShopRepairs[repair.Id] = (repair, count); + _logger.LogInformation("New repair added by supply. Added {0} of {1} in {2} shop", count, repair.RepairName, curModel.ShopName); + } + _shopStorage.Update(new() + { + Id = curModel.Id, + ShopName = curModel.ShopName, + Address = curModel.Address, + OpeningDate = curModel.OpeningDate, + ShopRepairs = curModel.ShopRepairs, + MaxCapacity = curModel.MaxCapacity + }); + } + else + { + _logger.LogWarning("Required shop is overflowed"); + return false; + } + return true; } - if (repair == null) - throw new ArgumentNullException(nameof(repair)); - if (count <= 0) - throw new ArgumentException("Количество должно быть положительным числом"); - - //попытка найти информацию о товаре в магазине по его идентификатору в словаре - //найден и добавляется - if (curModel.ShopRepairs.TryGetValue(repair.Id, out var pair)) - { - curModel.ShopRepairs[repair.Id] = (pair.Item1, pair.Item2 + count); - } - //не найден и добавляется - else - { - curModel.ShopRepairs.Add(repair.Id, (repair, count)); - } - Update(new() - { - Id = curModel.Id, - ShopName = curModel.ShopName, - OpeningDate = curModel.OpeningDate, - Address = curModel.Address, - ShopRepairs = curModel.ShopRepairs, - }); - _logger.LogInformation("Success. RepairName:{RepairName}. Id:{Id}. Replenish:{count}", - repair.RepairName, repair.Id, count); - return true; } - private void CheckModel(ShopBindingModel model, bool withParams = true) + private void CheckModel(ShopBindingModel model, bool withParams = true) { if (model == null) { @@ -150,6 +167,10 @@ namespace RenovationWorkBusinessLogic.BusinessLogics throw new InvalidOperationException("Магазин с таким названием уже есть"); } } + public bool SellRepairs(IRepairModel repair, int count) + { + return _shopStorage.SellRepairs(repair, count); + } } } diff --git a/RenovationWork/RenovationWorkContracts/BindingModels/ShopBindingModel.cs b/RenovationWork/RenovationWorkContracts/BindingModels/ShopBindingModel.cs index 9c22402..0965645 100644 --- a/RenovationWork/RenovationWorkContracts/BindingModels/ShopBindingModel.cs +++ b/RenovationWork/RenovationWorkContracts/BindingModels/ShopBindingModel.cs @@ -13,6 +13,7 @@ namespace RenovationWorkContracts.BindingModels public string ShopName { get; set; } = string.Empty; public string Address { get; set; } = string.Empty; public DateTime OpeningDate { get; set; } + public int MaxCapacity { get; set; } public Dictionary ShopRepairs { get; set; } = new(); } } diff --git a/RenovationWork/RenovationWorkContracts/BusinessLogicsContracts/IShopLogic.cs b/RenovationWork/RenovationWorkContracts/BusinessLogicsContracts/IShopLogic.cs index 391f396..110d4f6 100644 --- a/RenovationWork/RenovationWorkContracts/BusinessLogicsContracts/IShopLogic.cs +++ b/RenovationWork/RenovationWorkContracts/BusinessLogicsContracts/IShopLogic.cs @@ -18,5 +18,6 @@ namespace RenovationWorkContracts.BusinessLogicsContracts bool Update(ShopBindingModel model); bool Delete(ShopBindingModel model); bool ReplenishRepairs(ShopSearchModel shop, IRepairModel repair, int count); + bool SellRepairs(IRepairModel repair, int count); } } diff --git a/RenovationWork/RenovationWorkContracts/StoragesContracts/IShopStorage.cs b/RenovationWork/RenovationWorkContracts/StoragesContracts/IShopStorage.cs index ed014d5..71441ba 100644 --- a/RenovationWork/RenovationWorkContracts/StoragesContracts/IShopStorage.cs +++ b/RenovationWork/RenovationWorkContracts/StoragesContracts/IShopStorage.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using RenovationWorkContracts.BindingModels; using RenovationWorkContracts.SearchModels; using RenovationWorkContracts.ViewModels; +using RenovationWorkDataModels.Models; namespace RenovationWorkContracts.StoragesContracts { @@ -17,5 +18,6 @@ namespace RenovationWorkContracts.StoragesContracts ShopViewModel? Insert(ShopBindingModel model); ShopViewModel? Update(ShopBindingModel model); ShopViewModel? Delete(ShopBindingModel model); + public bool SellRepairs(IRepairModel model, int count); } } \ No newline at end of file diff --git a/RenovationWork/RenovationWorkContracts/ViewModels/ShopViewModel.cs b/RenovationWork/RenovationWorkContracts/ViewModels/ShopViewModel.cs index 8785459..8e78456 100644 --- a/RenovationWork/RenovationWorkContracts/ViewModels/ShopViewModel.cs +++ b/RenovationWork/RenovationWorkContracts/ViewModels/ShopViewModel.cs @@ -17,6 +17,8 @@ namespace RenovationWorkContracts.ViewModels public string Address { get; set; } = string.Empty; [DisplayName("Дата открытия")] public DateTime OpeningDate { get; set; } + [DisplayName("Вместимость")] + public int MaxCapacity { get; set; } public Dictionary ShopRepairs { get; set; } = new(); } } diff --git a/RenovationWork/RenovationWorkDataModels/Models/IShopModel.cs b/RenovationWork/RenovationWorkDataModels/Models/IShopModel.cs index 5b61a19..bd597ad 100644 --- a/RenovationWork/RenovationWorkDataModels/Models/IShopModel.cs +++ b/RenovationWork/RenovationWorkDataModels/Models/IShopModel.cs @@ -11,6 +11,7 @@ namespace RenovationWorkDataModels.Models string ShopName { get; } string Address { get; } DateTime OpeningDate { get; } + int MaxCapacity { get; } Dictionary ShopRepairs { get; } } } diff --git a/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs b/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs index 687b0be..4dff837 100644 --- a/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs +++ b/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs @@ -15,6 +15,8 @@ namespace RenovationWorkFileImplement private readonly string ComponentFileName = "Component.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string RepairFileName = "Repair.xml"; + private readonly string ShopFileName = "Shops.xml"; + public List Shops { get; private set; } public List Components { get; private set; } public List Orders { get; private set; } public List Repairs { get; private set; } @@ -27,10 +29,10 @@ namespace RenovationWorkFileImplement } return instance; } - public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); public void SaveRepairs() => SaveData(Repairs, RepairFileName, "Repairs", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + public void SaveShops() => SaveData(Shops, ShopFileName,"Shops", x => x.GetXElement); private DataFileSingleton() { Components = LoadData(ComponentFileName, "Component", x => @@ -39,6 +41,8 @@ namespace RenovationWorkFileImplement Repair.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/RenovationWork/RenovationWorkFileImplement/Implements/ShopStorage.cs b/RenovationWork/RenovationWorkFileImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..5df01af --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/Implements/ShopStorage.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RenovationWorkFileImplement; +using RenovationWorkContracts.BindingModels; +using RenovationWorkContracts.SearchModels; +using RenovationWorkContracts.StoragesContracts; +using RenovationWorkContracts.ViewModels; +using RenovationWorkDataModels.Models; +using RenovationWorkFileImplement.Models; + +namespace RenovationWorkFileImplement.Implements +{ + public class ShopStorage : IShopStorage + { + private readonly DataFileSingleton _source; + public ShopStorage() + { + _source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return _source.Shops + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ShopSearchModel + model) + { + if (string.IsNullOrEmpty(model.ShopName)) + { + return new(); + } + return _source.Shops + .Where(x => x.ShopName.Contains(model.ShopName)) + .Select(x => x.GetViewModel) + .ToList(); ; + } + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue) + { + return null; + } + return _source.Shops + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) && x.ShopName == + model.ShopName) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + public ShopViewModel? Insert(ShopBindingModel model) + { + model.Id = _source.Shops.Count > 0 ? _source.Shops.Max(x => + x.Id) + 1 : 1; + var newShop = Shop.Create(model); + if (newShop == null) + { + return null; + } + _source.Shops.Add(newShop); + _source.SaveShops(); + return newShop.GetViewModel; + } + public ShopViewModel? Update(ShopBindingModel model) + { + var component = _source.Shops.FirstOrDefault(x => x.Id == + model.Id); + if (component == null) + { + return null; + } + component.Update(model); + _source.SaveShops(); + return component.GetViewModel; + } + public ShopViewModel? Delete(ShopBindingModel model) + { + var element = _source.Shops.FirstOrDefault(x => x.Id == + model.Id); + if (element != null) + { + _source.Shops.Remove(element); + _source.SaveShops(); + return element.GetViewModel; + } + return null; + } + private bool CheckSell(int RepairId, int count) + { + count -= _source.Shops.Select(x => x.ShopRepairs.Select(y => + (y.Value.Item1.Id == RepairId ? y.Value.Item2 : 0)).Sum()).Sum(); + return count <= 0; + } + public bool SellRepairs(IRepairModel model, int count) + { + var neededRepair = _source.Repairs.FirstOrDefault(x => x.Id == model.Id); + if (neededRepair == null || !CheckSell(neededRepair.Id, count)) + { + return false; + } + for (int i = 0; i < _source.Shops.Count; i++) + { + var shop = _source.Shops[i]; + var assortment = shop.ShopRepairs; + foreach (var repair in assortment.Where(x => x.Value.Item1.Id == neededRepair.Id)) + { + var min = Math.Min(repair.Value.Item2, count); + assortment[repair.Value.Item1.Id] = (repair.Value.Item1, repair.Value.Item2 - min); + count -= min; + if (count <= 0) + { + break; + } + } + shop.Update(new ShopBindingModel + { + Id = shop.Id, + ShopName = shop.ShopName, + Address = shop.Address, + OpeningDate = shop.OpeningDate, + MaxCapacity = shop.MaxCapacity, + ShopRepairs = assortment + }); + } + _source.SaveShops(); + return true; + } + } +} diff --git a/RenovationWork/RenovationWorkFileImplement/Models/Shop.cs b/RenovationWork/RenovationWorkFileImplement/Models/Shop.cs new file mode 100644 index 0000000..adbbbe0 --- /dev/null +++ b/RenovationWork/RenovationWorkFileImplement/Models/Shop.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RenovationWorkFileImplement; +using RenovationWorkContracts.BindingModels; +using RenovationWorkContracts.ViewModels; +using RenovationWorkDataModels.Models; +using System.Xml.Linq; + +namespace RenovationWorkFileImplement.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 OpeningDate { get; private set; } + public int MaxCapacity { get; private set; } + public Dictionary Repairs { get; private set; } = new(); + private Dictionary? _shopRepairs = null; + public Dictionary ShopRepairs + { + get + { + if (_shopRepairs == null) + { + var source = DataFileSingleton.GetInstance(); + _shopRepairs = Repairs.ToDictionary(x => x.Key, y => + ((source.Repairs.FirstOrDefault(z => z.Id == y.Key) as IRepairModel)!, + y.Value)); + } + return _shopRepairs; + } + } + public static Shop? Create(ShopBindingModel model) + { + if (model == null) + return null; + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + OpeningDate = model.OpeningDate, + MaxCapacity = model.MaxCapacity, + Repairs = model.ShopRepairs.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, + MaxCapacity = Convert.ToInt32(element.Element("MaxCapacity")!.Value), + OpeningDate = Convert.ToDateTime(element.Element("DateOpen")!.Value), + Repairs = element.Element("ShopRepairs")!.Elements("ShopRepair") + .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; + OpeningDate = model.OpeningDate; + MaxCapacity = model.MaxCapacity; + if (model.ShopRepairs.Count > 0) + { + Repairs = model.ShopRepairs.ToDictionary(x => x.Key, x => x.Value.Item2); + _shopRepairs = null; + } + } + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + OpeningDate = OpeningDate, + MaxCapacity = MaxCapacity, + ShopRepairs = ShopRepairs + }; + public XElement GetXElement => new("Shop", + new XAttribute("Id", Id), + new XElement("ShopName", ShopName), + new XElement("Address", Address), + new XElement("DateOpen", OpeningDate), + new XElement("MaxCapacity", MaxCapacity), + new XElement("ShopRepairs", Repairs + .Select(x => new XElement("ShopRepair", + new XElement("Key", x.Key), + new XElement("Value", x.Value)) + ).ToArray())); + } +} diff --git a/RenovationWork/RenovationWorkListImplement/Implements/ShopStorage.cs b/RenovationWork/RenovationWorkListImplement/Implements/ShopStorage.cs index 67bfde4..ffc1e95 100644 --- a/RenovationWork/RenovationWorkListImplement/Implements/ShopStorage.cs +++ b/RenovationWork/RenovationWorkListImplement/Implements/ShopStorage.cs @@ -7,6 +7,7 @@ using RenovationWorkContracts.BindingModels; using RenovationWorkContracts.SearchModels; using RenovationWorkContracts.StoragesContracts; using RenovationWorkContracts.ViewModels; +using RenovationWorkDataModels.Models; using RenovationWorkListImplement.Models; namespace RenovationWorkListImplement.Implements @@ -103,5 +104,9 @@ namespace RenovationWorkListImplement.Implements } return null; } + public bool SellRepairs(IRepairModel model, int count) + { + throw new NotImplementedException(); + } } } diff --git a/RenovationWork/RenovationWorkListImplement/Models/Shop.cs b/RenovationWork/RenovationWorkListImplement/Models/Shop.cs index 6839e2b..577942f 100644 --- a/RenovationWork/RenovationWorkListImplement/Models/Shop.cs +++ b/RenovationWork/RenovationWorkListImplement/Models/Shop.cs @@ -50,5 +50,6 @@ namespace RenovationWorkListImplement.Models OpeningDate = OpeningDate, ShopRepairs = ShopRepairs }; + public int MaxCapacity => throw new NotImplementedException(); } } -- 2.25.1 From 14c5a5991c313976a160c885fd839ef78967bdd3 Mon Sep 17 00:00:00 2001 From: "yuliya.mavrina@internet.ru" Date: Tue, 23 Apr 2024 15:48:49 +0300 Subject: [PATCH 3/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=5F2=D1=81=D0=BB=D0=BE?= =?UTF-8?q?=D0=B6=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/OrderLogic.cs | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs index b09d8a2..c98ff20 100644 --- a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs @@ -49,14 +49,15 @@ namespace RenovationWorkBusinessLogic.BusinessLogics } private bool StatusUpdate(OrderBindingModel model, OrderStatus status) { - CheckModel(model); + var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); if (element == null) { _logger.LogWarning("Read operation failed"); return false; } - if (element.Status != status - 1) + CheckModel(element); + if (element.Status != status - 1) { _logger.LogWarning("Status change operation failed"); throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный"); @@ -130,7 +131,31 @@ namespace RenovationWorkBusinessLogic.BusinessLogics } _logger.LogInformation("Order. Count: {Count}. Sum: {Sum}. Id: {Id}", model.Count, model.Sum, model.Id); } - private bool CheckSupply(IRepairModel repair, int count) + private void CheckModel(OrderViewModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (model.RepairId < 0) + { + throw new ArgumentNullException("Некорректный идентификатор документа", nameof(model.RepairId)); + } + if (model.Count <= 0) + { + throw new ArgumentNullException("Количество работ в заказе должно быть больше 0", nameof(model.Count)); + } + if (model.Sum <= 0) + { + throw new ArgumentNullException("Сумма заказа должна быть больше 0", nameof(model.Sum)); + } + _logger.LogInformation("Order. Count: {Count}. Sum: {Sum}. Id: {Id}", model.Count, model.Sum, model.Id); + } + private bool CheckSupply(IRepairModel repair, int count) { if (count <= 0) { -- 2.25.1 From 85dc0d0ddd52b17d87f9215d5a0df66ed9db0b64 Mon Sep 17 00:00:00 2001 From: "yuliya.mavrina@internet.ru" Date: Tue, 23 Apr 2024 15:52:38 +0300 Subject: [PATCH 4/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=5F2=D1=81=D0=BB=D0=BE?= =?UTF-8?q?=D0=B6=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/OrderLogic.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs index c98ff20..4c03d03 100644 --- a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs @@ -64,13 +64,13 @@ namespace RenovationWorkBusinessLogic.BusinessLogics } if (element.Status == OrderStatus.Готов) { - var manufacture = _repairStorage.GetElement(new RepairSearchModel() { Id = model.RepairId }); - if (manufacture == null) + var repair = _repairStorage.GetElement(new RepairSearchModel() { Id = model.RepairId }); + if (repair == null) { _logger.LogWarning("Status update to " + status.ToString() + " operation failed. Document not found."); return false; } - if (CheckSupply(manufacture, model.Count) == false) + if (CheckSupply(repair, model.Count) == false) { _logger.LogWarning("Status update to " + status.ToString() + " operation failed. Shop supply error."); return false; -- 2.25.1 From 80550c60fd7a85c8b637c32379ccf4ab0d19e9bc Mon Sep 17 00:00:00 2001 From: "yuliya.mavrina@internet.ru" Date: Tue, 23 Apr 2024 22:08:26 +0300 Subject: [PATCH 5/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=5F2=D1=81=D0=BB=D0=BE?= =?UTF-8?q?=D0=B6=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RenovationWork/RenovationWork/FormMain.cs | 47 +++++++++---------- .../BusinessLogics/OrderLogic.cs | 5 +- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/RenovationWork/RenovationWork/FormMain.cs b/RenovationWork/RenovationWork/FormMain.cs index 24293da..a968b62 100644 --- a/RenovationWork/RenovationWork/FormMain.cs +++ b/RenovationWork/RenovationWork/FormMain.cs @@ -108,9 +108,7 @@ namespace RenovationWorkView _logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id); try { - var operationResult = _orderLogic.FinishOrder(new - OrderBindingModel - { Id = id }); + var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id }); if (!operationResult) { throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); @@ -127,28 +125,27 @@ namespace RenovationWorkView private void buttonIssuedOrder_Click(object sender, EventArgs e) { - if (dataGridView.SelectedRows.Count == 1) - { - int id = - Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id); - try - { - var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id }); - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - _logger.LogInformation("Заказ №{id} выдан", id); - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка отметки о выдачи заказа"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } + if (dataGridView.SelectedRows.Count == 1) + { + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Заказ No{id}. Меняется статус на 'Выдан'", id); + try + { + var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel {Id = id}); + if (!operationResult) + { + throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); + } + _logger.LogInformation("Заказ No{id} выдан", id); + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка отметки о выдачи заказа"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } private void buttonRef_Click(object sender, EventArgs e) { diff --git a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs index 4c03d03..2795148 100644 --- a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs @@ -49,15 +49,14 @@ namespace RenovationWorkBusinessLogic.BusinessLogics } private bool StatusUpdate(OrderBindingModel model, OrderStatus status) { - var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); if (element == null) { _logger.LogWarning("Read operation failed"); return false; } - CheckModel(element); - if (element.Status != status - 1) + CheckModel(element); + if (element.Status != status - 1) { _logger.LogWarning("Status change operation failed"); throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный"); -- 2.25.1 From 136591c7a7aadd66dd8d0169484c44f9b66a58d3 Mon Sep 17 00:00:00 2001 From: "yuliya.mavrina@internet.ru" Date: Sun, 19 May 2024 23:49:58 +0300 Subject: [PATCH 6/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=5F2=D1=81=D0=BB=D0=BE?= =?UTF-8?q?=D0=B6=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RenovationWork/RenovationWork/FormMain.cs | 108 +++--- .../BusinessLogics/OrderLogic.cs | 322 ++++++++---------- .../BusinessLogics/ShopLogic.cs | 321 +++++++++-------- .../DataFileSingleton.cs | 104 +++--- .../Implements/OrderStorage.cs | 158 +++++---- 5 files changed, 497 insertions(+), 516 deletions(-) diff --git a/RenovationWork/RenovationWork/FormMain.cs b/RenovationWork/RenovationWork/FormMain.cs index a968b62..3344d1a 100644 --- a/RenovationWork/RenovationWork/FormMain.cs +++ b/RenovationWork/RenovationWork/FormMain.cs @@ -10,6 +10,7 @@ using System.Windows.Forms; using RenovationWorkContracts.BindingModels; using RenovationWorkContracts.BusinessLogicsContracts; using Microsoft.Extensions.Logging; +using RenovationWorkDataModels.Enums; namespace RenovationWorkView { @@ -76,54 +77,67 @@ namespace RenovationWorkView } } - private void buttonTakeOrderInWork_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id); - try - { - var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { Id = id }); - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка передачи заказа в работу"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } + private OrderBindingModel CreateBindingModel(int id, bool isDone = false) + { + return new OrderBindingModel + { + Id = id, + RepairId = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["RepairId"].Value), + Status = Enum.Parse(dataGridView.SelectedRows[0].Cells["Status"].Value.ToString()), + Count = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Count"].Value), + Sum = double.Parse(dataGridView.SelectedRows[0].Cells["Sum"].Value.ToString()), + DateCreate = DateTime.Parse(dataGridView.SelectedRows[0].Cells["DateCreate"].Value.ToString()), + }; + } - private void buttonOrderReady_Click(object sender, EventArgs e) + private void buttonTakeOrderInWork_Click(object sender, EventArgs e) { - if (dataGridView.SelectedRows.Count == 1) - { - int id = - Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id); - try - { - var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id }); - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка отметки о готовности заказа"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } + if (dataGridView.SelectedRows.Count == 1) + { + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id); + try + { + var operationResult = _orderLogic.TakeOrderInWork(CreateBindingModel(id)); + if (!operationResult) + { + throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка передачи заказа в работу"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } - private void buttonIssuedOrder_Click(object sender, EventArgs e) + private void buttonOrderReady_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + int id = + Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id); + try + { + var operationResult = _orderLogic.FinishOrder(CreateBindingModel(id)); + if (!operationResult) + { + throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка отметки о готовности заказа"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void buttonIssuedOrder_Click(object sender, EventArgs e) { if (dataGridView.SelectedRows.Count == 1) { @@ -131,7 +145,7 @@ namespace RenovationWorkView _logger.LogInformation("Заказ No{id}. Меняется статус на 'Выдан'", id); try { - var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel {Id = id}); + var operationResult = _orderLogic.DeliveryOrder(CreateBindingModel(id)); if (!operationResult) { throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); @@ -147,7 +161,7 @@ namespace RenovationWorkView } } - private void buttonRef_Click(object sender, EventArgs e) + private void buttonRef_Click(object sender, EventArgs e) { LoadData(); } diff --git a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs index 2795148..e239cec 100644 --- a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/OrderLogic.cs @@ -14,123 +14,99 @@ using Microsoft.Extensions.Logging; namespace RenovationWorkBusinessLogic.BusinessLogics { - public class OrderLogic : IOrderLogic - { - private readonly ILogger _logger; - private readonly IOrderStorage _orderStorage; - private readonly IShopLogic _shopLogic; - private readonly IRepairStorage _repairStorage; - private readonly IShopStorage _shopStorage; - public OrderLogic(ILogger logger, IOrderStorage orderStorage, - IRepairStorage repairStorage, IShopLogic shopLogic, IShopStorage shopStorage) - { - _logger = logger; - _orderStorage = orderStorage; - _repairStorage = repairStorage; - _shopLogic = shopLogic; - _shopStorage = shopStorage; - } - public bool CreateOrder(OrderBindingModel model) - { - CheckModel(model); - if (model.Status != OrderStatus.Неизвестен) - { - _logger.LogWarning("Insert operation failed. Order status incorrect."); - return false; - } - model.Status = OrderStatus.Принят; - if (_orderStorage.Insert(model) == null) - { - model.Status = OrderStatus.Неизвестен; - _logger.LogWarning("Insert operation failed"); - return false; - } - return true; - } - private bool StatusUpdate(OrderBindingModel model, OrderStatus status) - { - var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); - if (element == null) - { - _logger.LogWarning("Read operation failed"); - return false; - } - CheckModel(element); - if (element.Status != status - 1) - { - _logger.LogWarning("Status change operation failed"); - throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный"); - } - if (element.Status == OrderStatus.Готов) - { - var repair = _repairStorage.GetElement(new RepairSearchModel() { Id = model.RepairId }); - if (repair == null) - { - _logger.LogWarning("Status update to " + status.ToString() + " operation failed. Document not found."); - return false; - } - if (CheckSupply(repair, model.Count) == false) - { - _logger.LogWarning("Status update to " + status.ToString() + " operation failed. Shop supply error."); - return false; - } - } - model.Status = status; - if (model.Status == OrderStatus.Выдан) - model.DateImplement = DateTime.Now; - _orderStorage.Update(model); - return true; - } - public bool DeliveryOrder(OrderBindingModel model) - { - return StatusUpdate(model, OrderStatus.Выдан); - } + public class OrderLogic : IOrderLogic + { + private readonly ILogger _logger; + private readonly IOrderStorage _orderStorage; + private readonly IShopLogic _shopLogic; + private readonly IRepairStorage _repairStorage; + private readonly IShopStorage _shopStorage; + public OrderLogic(ILogger logger, IOrderStorage orderStorage, + IRepairStorage repairStorage, IShopLogic shopLogic, IShopStorage shopStorage) + { + _logger = logger; + _orderStorage = orderStorage; + _repairStorage = repairStorage; + _shopLogic = shopLogic; + _shopStorage = shopStorage; + } + public bool CreateOrder(OrderBindingModel model) + { + CheckModel(model); + if (model.Status != OrderStatus.Неизвестен) + { + _logger.LogWarning("Insert operation failed. Order status incorrect."); + return false; + } + model.Status = OrderStatus.Принят; + if (_orderStorage.Insert(model) == null) + { + model.Status = OrderStatus.Неизвестен; + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + private bool StatusUpdate(OrderBindingModel model, OrderStatus status) + { + CheckModel(model); + var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); + if (element == null) + { + _logger.LogWarning("Read operation failed"); + return false; + } + if (element.Status != status - 1) + { + _logger.LogWarning("Status change operation failed"); + throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный"); + } + if (element.Status == OrderStatus.Готов) + { + var repair = _repairStorage.GetElement(new RepairSearchModel() { Id = model.RepairId }); + if (repair == null) + { + _logger.LogWarning("Status update to " + status.ToString() + " operation failed. Document not found."); + return false; + } + if (CheckSupply(repair, model.Count) == false) + { + _logger.LogWarning("Status update to " + status.ToString() + " operation failed. Shop supply error."); + return false; + } + } + model.Status = status; + if (model.Status == OrderStatus.Выдан) + model.DateImplement = DateTime.Now; + _orderStorage.Update(model); + return true; + } + public bool DeliveryOrder(OrderBindingModel model) + { + return StatusUpdate(model, OrderStatus.Выдан); + } - public bool FinishOrder(OrderBindingModel model) - { - return StatusUpdate(model, OrderStatus.Готов); - } - public bool TakeOrderInWork(OrderBindingModel model) - { - return StatusUpdate(model, OrderStatus.Выполняется); - } - public List? ReadList(OrderSearchModel? model) - { - _logger.LogInformation("ReadList. OrderId:{Id}", model?.Id); - var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model); - if (list == null) - { - _logger.LogWarning("ReadList return null list"); - return null; - } - _logger.LogInformation("ReadList. Count:{Count}", list.Count); - return list; - } - private void CheckModel(OrderBindingModel model, bool withParams = true) - { - if (model == null) - { - throw new ArgumentNullException(nameof(model)); - } - if (!withParams) - { - return; - } - if (model.RepairId < 0) - { - throw new ArgumentNullException("Некорректный идентификатор документа", nameof(model.RepairId)); - } - if (model.Count <= 0) - { - throw new ArgumentNullException("Количество работ в заказе должно быть больше 0", nameof(model.Count)); - } - if (model.Sum <= 0) - { - throw new ArgumentNullException("Сумма заказа должна быть больше 0", nameof(model.Sum)); - } - _logger.LogInformation("Order. Count: {Count}. Sum: {Sum}. Id: {Id}", model.Count, model.Sum, model.Id); - } - private void CheckModel(OrderViewModel model, bool withParams = true) + public bool FinishOrder(OrderBindingModel model) + { + return StatusUpdate(model, OrderStatus.Готов); + } + public bool TakeOrderInWork(OrderBindingModel model) + { + return StatusUpdate(model, OrderStatus.Выполняется); + } + public List? ReadList(OrderSearchModel? model) + { + _logger.LogInformation("ReadList. OrderId:{Id}", model?.Id); + var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + private void CheckModel(OrderBindingModel model, bool withParams = true) { if (model == null) { @@ -140,10 +116,6 @@ namespace RenovationWorkBusinessLogic.BusinessLogics { return; } - if (model.RepairId < 0) - { - throw new ArgumentNullException("Некорректный идентификатор документа", nameof(model.RepairId)); - } if (model.Count <= 0) { throw new ArgumentNullException("Количество работ в заказе должно быть больше 0", nameof(model.Count)); @@ -155,59 +127,59 @@ namespace RenovationWorkBusinessLogic.BusinessLogics _logger.LogInformation("Order. Count: {Count}. Sum: {Sum}. Id: {Id}", model.Count, model.Sum, model.Id); } private bool CheckSupply(IRepairModel repair, int count) - { - if (count <= 0) - { - _logger.LogWarning("Check then supply operation error. Repair count < 0."); - return false; - } - int sumCapacity = 0; - int sumCount = 0; - sumCapacity = _shopStorage.GetFullList().Select(x => x.MaxCapacity).Sum(); - sumCount = _shopStorage.GetFullList().Select(x => x.ShopRepairs.Select(y => y.Value.Item2).Sum()).Sum(); - int freeSpace = sumCapacity - sumCount; - if (freeSpace - count < 0) - { - _logger.LogWarning("Check then supply operation error. There's no place for new Repair in shops."); - return false; - } - foreach (var shop in _shopStorage.GetFullList()) - { - freeSpace = shop.MaxCapacity; - foreach (var doc in shop.ShopRepairs) - { - freeSpace -= doc.Value.Item2; - } - if (freeSpace == 0) - { - continue; - } - if (freeSpace - count >= 0) - { - if (_shopLogic.ReplenishRepairs(new() { Id = shop.Id }, repair, count)) - count = 0; - else - { - _logger.LogWarning("Supply error"); - return false; - } - } - if (freeSpace - count < 0) - { - if (_shopLogic.ReplenishRepairs(new() { Id = shop.Id }, repair, freeSpace)) - count -= freeSpace; - else - { - _logger.LogWarning("Supply error"); - return false; - } - } - if (count <= 0) - { - return true; - } - } - return false; - } - } + { + if (count <= 0) + { + _logger.LogWarning("Check then supply operation error. Repair count < 0."); + return false; + } + int sumCapacity = 0; + int sumCount = 0; + sumCapacity = _shopStorage.GetFullList().Select(x => x.MaxCapacity).Sum(); + sumCount = _shopStorage.GetFullList().Select(x => x.ShopRepairs.Select(y => y.Value.Item2).Sum()).Sum(); + int freeSpace = sumCapacity - sumCount; + if (freeSpace - count < 0) + { + _logger.LogWarning("Check then supply operation error. There's no place for new Repair in shops."); + return false; + } + foreach (var shop in _shopStorage.GetFullList()) + { + freeSpace = shop.MaxCapacity; + foreach (var doc in shop.ShopRepairs) + { + freeSpace -= doc.Value.Item2; + } + if (freeSpace == 0) + { + continue; + } + if (freeSpace - count >= 0) + { + if (_shopLogic.ReplenishRepairs(new() { Id = shop.Id }, repair, count)) + count = 0; + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + if (freeSpace - count < 0) + { + if (_shopLogic.ReplenishRepairs(new() { Id = shop.Id }, repair, freeSpace)) + count -= freeSpace; + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + if (count <= 0) + { + return true; + } + } + return false; + } + } } \ No newline at end of file diff --git a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/ShopLogic.cs b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/ShopLogic.cs index 53ffe56..e469ca8 100644 --- a/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/ShopLogic.cs +++ b/RenovationWork/RenovationWorkBusinessLogic/BusinessLogics/ShopLogic.cs @@ -13,164 +13,163 @@ using Microsoft.Extensions.Logging; namespace RenovationWorkBusinessLogic.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 ReplenishRepairs(ShopSearchModel model, IRepairModel repair, int count) - { - { - _logger.LogInformation("Try to replenish repairs. ShopName:{ShopName}. Id:{Id}", model.ShopName, model.Id); - if (model == null) - { - _logger.LogWarning("Read operation failed"); - throw new ArgumentNullException(nameof(model)); - } - ShopViewModel? curModel = ReadElement(model); - if (curModel == null) - { - _logger.LogWarning("Read operation failed"); - throw new ArgumentNullException(nameof(curModel)); - } - if (repair == null) - { - _logger.LogWarning("Read operation failed"); - throw new ArgumentNullException(nameof(repair)); - } - if (count <= 0) - { - _logger.LogWarning("Read operation failed"); - throw new ArgumentException("Количество должно быть положительным"); - } - int countItems = curModel.ShopRepairs.Select(x => x.Value.Item2).Sum(); - if (curModel.MaxCapacity - countItems >= count) - { - if (curModel.ShopRepairs.TryGetValue(repair.Id, out var sameDocument)) - { - curModel.ShopRepairs[repair.Id] = (repair, sameDocument.Item2 + count); - _logger.LogInformation("Same repair found by supply. Added {0} of {1} in {2} shop", count, repair.RepairName, curModel.ShopName); - } - else - { - curModel.ShopRepairs[repair.Id] = (repair, count); - _logger.LogInformation("New repair added by supply. Added {0} of {1} in {2} shop", count, repair.RepairName, curModel.ShopName); - } - _shopStorage.Update(new() - { - Id = curModel.Id, - ShopName = curModel.ShopName, - Address = curModel.Address, - OpeningDate = curModel.OpeningDate, - ShopRepairs = curModel.ShopRepairs, - MaxCapacity = curModel.MaxCapacity - }); - } - else - { - _logger.LogWarning("Required shop is overflowed"); - 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}. DateOpen:{DateOpen}. Id: { Id}", - model.ShopName, model.Address, model.OpeningDate, model.Id); - var element = _shopStorage.GetElement(new ShopSearchModel - { - ShopName = model.ShopName - }); - if (element != null && element.Id != model.Id) - { - throw new InvalidOperationException("Магазин с таким названием уже есть"); - } - } - public bool SellRepairs(IRepairModel repair, int count) - { - return _shopStorage.SellRepairs(repair, count); - } - } -} - + 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 ReplenishRepairs(ShopSearchModel model, IRepairModel repair, int count) + { + { + _logger.LogInformation("Try to replenish repairs. ShopName:{ShopName}. Id:{Id}", model.ShopName, model.Id); + if (model == null) + { + _logger.LogWarning("Read operation failed"); + throw new ArgumentNullException(nameof(model)); + } + ShopViewModel? curModel = ReadElement(model); + if (curModel == null) + { + _logger.LogWarning("Read operation failed"); + throw new ArgumentNullException(nameof(curModel)); + } + if (repair == null) + { + _logger.LogWarning("Read operation failed"); + throw new ArgumentNullException(nameof(repair)); + } + if (count <= 0) + { + _logger.LogWarning("Read operation failed"); + throw new ArgumentException("Количество должно быть положительным"); + } + int countItems = curModel.ShopRepairs.Select(x => x.Value.Item2).Sum(); + if (curModel.MaxCapacity - countItems >= count) + { + if (curModel.ShopRepairs.TryGetValue(repair.Id, out var sameDocument)) + { + curModel.ShopRepairs[repair.Id] = (repair, sameDocument.Item2 + count); + _logger.LogInformation("Same repair found by supply. Added {0} of {1} in {2} shop", count, repair.RepairName, curModel.ShopName); + } + else + { + curModel.ShopRepairs[repair.Id] = (repair, count); + _logger.LogInformation("New repair added by supply. Added {0} of {1} in {2} shop", count, repair.RepairName, curModel.ShopName); + } + _shopStorage.Update(new() + { + Id = curModel.Id, + ShopName = curModel.ShopName, + Address = curModel.Address, + OpeningDate = curModel.OpeningDate, + ShopRepairs = curModel.ShopRepairs, + MaxCapacity = curModel.MaxCapacity + }); + } + else + { + _logger.LogWarning("Required shop is overflowed"); + 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}. DateOpen:{DateOpen}. Id: { Id}", + model.ShopName, model.Address, model.OpeningDate, model.Id); + var element = _shopStorage.GetElement(new ShopSearchModel + { + ShopName = model.ShopName + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Магазин с таким названием уже есть"); + } + } + public bool SellRepairs(IRepairModel repair, int count) + { + return _shopStorage.SellRepairs(repair, count); + } + } +} \ No newline at end of file diff --git a/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs b/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs index 4dff837..3ceceb5 100644 --- a/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs +++ b/RenovationWork/RenovationWorkFileImplement/DataFileSingleton.cs @@ -9,59 +9,59 @@ using RenovationWorkFileImplement.Models; namespace RenovationWorkFileImplement { - internal class DataFileSingleton - { - private static DataFileSingleton? instance; - private readonly string ComponentFileName = "Component.xml"; - private readonly string OrderFileName = "Order.xml"; - private readonly string RepairFileName = "Repair.xml"; - private readonly string ShopFileName = "Shops.xml"; - public List Shops { get; private set; } - public List Components { get; private set; } - public List Orders { get; private set; } - public List Repairs { get; private set; } + internal class DataFileSingleton + { + private static DataFileSingleton? instance; + private readonly string ComponentFileName = "Component.xml"; + private readonly string OrderFileName = "Order.xml"; + private readonly string RepairFileName = "Repair.xml"; + private readonly string ShopFileName = "Shops.xml"; + public List Shops { get; private set; } + public List Components { get; private set; } + public List Orders { get; private set; } + public List Repairs { get; private set; } - public static DataFileSingleton GetInstance() - { - if (instance == null) - { - instance = new DataFileSingleton(); - } - return instance; - } - public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); - public void SaveRepairs() => SaveData(Repairs, RepairFileName, "Repairs", x => x.GetXElement); - public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); - public void SaveShops() => SaveData(Shops, ShopFileName,"Shops", x => x.GetXElement); - private DataFileSingleton() - { - Components = LoadData(ComponentFileName, "Component", x => - Component.Create(x)!)!; - Repairs = LoadData(RepairFileName, "Repair", x => - Repair.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) - { - 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); - } - } + public static DataFileSingleton GetInstance() + { + if (instance == null) + { + instance = new DataFileSingleton(); + } + return instance; + } + public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); + public void SaveRepairs() => SaveData(Repairs, RepairFileName, "Repairs", x => x.GetXElement); + public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", x => x.GetXElement); + private DataFileSingleton() + { + Components = LoadData(ComponentFileName, "Component", x => + Component.Create(x)!)!; + Repairs = LoadData(RepairFileName, "Repair", x => + Repair.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) + { + 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); + } + } - } + } } \ No newline at end of file diff --git a/RenovationWork/RenovationWorkFileImplement/Implements/OrderStorage.cs b/RenovationWork/RenovationWorkFileImplement/Implements/OrderStorage.cs index 586c135..b873f6a 100644 --- a/RenovationWork/RenovationWorkFileImplement/Implements/OrderStorage.cs +++ b/RenovationWork/RenovationWorkFileImplement/Implements/OrderStorage.cs @@ -11,86 +11,82 @@ using RenovationWorkFileImplement.Models; namespace RenovationWorkFileImplement.Implements { - public class OrderStorage : IOrderStorage - { - private readonly DataFileSingleton source; - public OrderStorage() - { - source = DataFileSingleton.GetInstance(); - } - public List GetFullList() - { - return source.Orders.Select(x => AccessRepairStorage(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 => AccessRepairStorage(x.GetViewModel)) - .ToList(); - } - public OrderViewModel? GetElement(OrderSearchModel model) - { - if (!model.Id.HasValue) - { - return null; - } - return AccessRepairStorage(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 AccessRepairStorage(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 AccessRepairStorage(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 AccessRepairStorage(element.GetViewModel); - } - return null; - } - public OrderViewModel? AccessRepairStorage(OrderViewModel model) - { - if (model == null) - return null; - foreach (var Repair in source.Repairs) - { - if (Repair.Id == model.RepairId) - { - model.RepairName = Repair.RepairName; - break; - } - } - return model; - } - } + public class OrderStorage : IOrderStorage + { + private readonly DataFileSingleton source; + public OrderStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Orders.Select(x => AccessRepairStorage(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 => AccessRepairStorage(x.GetViewModel)) + .ToList(); + } + public OrderViewModel? GetElement(OrderSearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + return AccessRepairStorage(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 AccessRepairStorage(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 AccessRepairStorage(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 AccessRepairStorage(element.GetViewModel); + } + return null; + } + public OrderViewModel? AccessRepairStorage(OrderViewModel model) + { + if (model == null) + return null; + var repair = source.Repairs.FirstOrDefault(x => (x.Id == model.RepairId)); + if (repair == null) + return model; + model.RepairName = repair.RepairName; + return model; + } + } } -- 2.25.1 From 731cc522d87448196cba970293dddac16ac3fe97 Mon Sep 17 00:00:00 2001 From: "yuliya.mavrina@internet.ru" Date: Mon, 3 Jun 2024 09:53:00 +0300 Subject: [PATCH 7/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=5F2=D1=81=D0=BB=D0=BE?= =?UTF-8?q?=D0=B6=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RenovationWorkFileImplement/Implements/ShopStorage.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/RenovationWork/RenovationWorkFileImplement/Implements/ShopStorage.cs b/RenovationWork/RenovationWorkFileImplement/Implements/ShopStorage.cs index 5df01af..90385e8 100644 --- a/RenovationWork/RenovationWorkFileImplement/Implements/ShopStorage.cs +++ b/RenovationWork/RenovationWorkFileImplement/Implements/ShopStorage.cs @@ -85,12 +85,14 @@ namespace RenovationWorkFileImplement.Implements } return null; } + private bool CheckSell(int RepairId, int count) { - count -= _source.Shops.Select(x => x.ShopRepairs.Select(y => - (y.Value.Item1.Id == RepairId ? y.Value.Item2 : 0)).Sum()).Sum(); - return count <= 0; + int availableCount = _source.Shops.Sum(x => x.ShopRepairs + .Where(y => y.Value.Item1.Id == RepairId).Sum(y => y.Value.Item2)); + return count <= availableCount; } + public bool SellRepairs(IRepairModel model, int count) { var neededRepair = _source.Repairs.FirstOrDefault(x => x.Id == model.Id); -- 2.25.1