From 1673c9206c8230c0ce361fe52b82010926e2d5c7 Mon Sep 17 00:00:00 2001 From: sardq Date: Sat, 23 Mar 2024 19:49:48 +0400 Subject: [PATCH 1/3] =?UTF-8?q?2=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=BD=D0=B0=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PlumbingRepair/PlumbingRepair.sln | 6 ++ .../DataFileSingleton.cs | 61 ++++++++++++ .../Implements/ComponentStorage.cs | 86 +++++++++++++++++ .../Implements/OrderStorage.cs | 93 ++++++++++++++++++ .../Implements/WorkStorage.cs | 85 +++++++++++++++++ .../Models/Component.cs | 66 +++++++++++++ .../Models/Order.cs | 94 +++++++++++++++++++ .../Models/Work.cs | 93 ++++++++++++++++++ .../PlumbingRepairFileImplement.csproj | 18 ++++ .../PlumbingRepairView.csproj | 1 + PlumbingRepair/PlumbingRepairView/Program.cs | 2 +- 11 files changed, 604 insertions(+), 1 deletion(-) create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/DataFileSingleton.cs create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/Implements/ComponentStorage.cs create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/Implements/OrderStorage.cs create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/Implements/WorkStorage.cs create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/Models/Component.cs create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/Models/Order.cs create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/Models/Work.cs create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/PlumbingRepairFileImplement.csproj diff --git a/PlumbingRepair/PlumbingRepair.sln b/PlumbingRepair/PlumbingRepair.sln index 9fef091..ddbe19f 100644 --- a/PlumbingRepair/PlumbingRepair.sln +++ b/PlumbingRepair/PlumbingRepair.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlumbingRepairDataModels", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlumbingRepairListImplement", "PlumbingRepairListImplement\PlumbingRepairListImplement.csproj", "{A5D22B59-19BC-4DB6-A234-24AEA47605C2}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlumbingRepairFileImplement", "PlumbingRepairFileImplement\PlumbingRepairFileImplement.csproj", "{8BB0E6DF-704B-4660-8D5E-4D263CD40C98}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {A5D22B59-19BC-4DB6-A234-24AEA47605C2}.Debug|Any CPU.Build.0 = Debug|Any CPU {A5D22B59-19BC-4DB6-A234-24AEA47605C2}.Release|Any CPU.ActiveCfg = Release|Any CPU {A5D22B59-19BC-4DB6-A234-24AEA47605C2}.Release|Any CPU.Build.0 = Release|Any CPU + {8BB0E6DF-704B-4660-8D5E-4D263CD40C98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8BB0E6DF-704B-4660-8D5E-4D263CD40C98}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8BB0E6DF-704B-4660-8D5E-4D263CD40C98}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8BB0E6DF-704B-4660-8D5E-4D263CD40C98}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PlumbingRepair/PlumbingRepairFileImplement/DataFileSingleton.cs b/PlumbingRepair/PlumbingRepairFileImplement/DataFileSingleton.cs new file mode 100644 index 0000000..10d3e85 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/DataFileSingleton.cs @@ -0,0 +1,61 @@ +using PlumbingRepairFileImplement.Models; +using System.Xml.Linq; + +namespace PlumbingRepairFileImplement +{ + internal class DataFileSingleton + { + private static DataFileSingleton? instance; + + private readonly string ComponentFileName = "Component.xml"; + + private readonly string OrderFileName = "Order.xml"; + + private readonly string WorkFileName = "Work.xml"; + + public List Components { get; private set; } + + public List Orders { get; private set; } + + public List Works { 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 SaveWorks() => SaveData(Works, WorkFileName, "Works", x => x.GetXElement); + + public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + + private DataFileSingleton() + { + Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!; + Works = LoadData(WorkFileName, "Work", x => Work.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/PlumbingRepair/PlumbingRepairFileImplement/Implements/ComponentStorage.cs b/PlumbingRepair/PlumbingRepairFileImplement/Implements/ComponentStorage.cs new file mode 100644 index 0000000..e425674 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/Implements/ComponentStorage.cs @@ -0,0 +1,86 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.StoragesContracts; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairFileImplement.Models; + +namespace PlumbingRepairFileImplement.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; + } + + 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/PlumbingRepair/PlumbingRepairFileImplement/Implements/OrderStorage.cs b/PlumbingRepair/PlumbingRepairFileImplement/Implements/OrderStorage.cs new file mode 100644 index 0000000..d4316ad --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/Implements/OrderStorage.cs @@ -0,0 +1,93 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.StoragesContracts; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairFileImplement.Models; + +namespace PlumbingRepairFileImplement.Implements +{ + public class OrderStorage : IOrderStorage + { + private readonly DataFileSingleton source; + public OrderStorage() + { + source = DataFileSingleton.GetInstance(); + } + 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 GetViewModel(element); + } + return null; + } + + public OrderViewModel? GetElement(OrderSearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + return GetViewModel(source.Orders.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)); + + } + + public List GetFilteredList(OrderSearchModel model) + { + if (!model.Id.HasValue) + { + return new(); + } + return source.Orders + .Where(x => x.Id == model.Id) + .Select(x => GetViewModel(x)) + .ToList(); + } + + public List GetFullList() + { + return source.Orders + .Select(x => GetViewModel(x)) + .ToList(); + } + + 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 GetViewModel(newOrder); + } + + 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 GetViewModel(order); + } + + private OrderViewModel GetViewModel(Order order) + { + var viewModel = order.GetViewModel; + var work = source.Works.FirstOrDefault(x => x.Id == order.WorkId); + if (work != null) + { + viewModel.WorkName = work.WorkName; + } + return viewModel; + } + } +} \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairFileImplement/Implements/WorkStorage.cs b/PlumbingRepair/PlumbingRepairFileImplement/Implements/WorkStorage.cs new file mode 100644 index 0000000..952c60a --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/Implements/WorkStorage.cs @@ -0,0 +1,85 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.StoragesContracts; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairFileImplement.Models; + +namespace PlumbingRepairFileImplement.Implements +{ + public class WorkStorage : IWorkStorage + { + private readonly DataFileSingleton source; + + public WorkStorage() + { + source = DataFileSingleton.GetInstance(); + } + public WorkViewModel? Delete(WorkBindingModel model) + { + var element = source.Works.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + source.Works.Remove(element); + source.SaveWorks(); + return element.GetViewModel; + } + return null; + } + + public WorkViewModel? GetElement(WorkSearchModel model) + { + if (string.IsNullOrEmpty(model.WorkName) && !model.Id.HasValue) + { + return null; + } + return source.Works + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.WorkName) && x.WorkName == model.WorkName) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + + public List GetFilteredList(WorkSearchModel model) + { + if (string.IsNullOrEmpty(model.WorkName)) + { + return new(); + } + return source.Works + .Where(x => x.WorkName.Contains(model.WorkName)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFullList() + { + return source.Works + .Select(x => x.GetViewModel) + .ToList(); + } + + public WorkViewModel? Insert(WorkBindingModel model) + { + model.Id = source.Works.Count > 0 ? source.Works.Max(x => x.Id) + 1 : 1; + var newWork = Work.Create(model); + if (newWork == null) + { + return null; + } + source.Works.Add(newWork); + source.SaveWorks(); + return newWork.GetViewModel; + } + + public WorkViewModel? Update(WorkBindingModel model) + { + var work = source.Works.FirstOrDefault(x => x.Id == model.Id); + if (work == null) + { + return null; + } + work.Update(model); + source.SaveWorks(); + return work.GetViewModel; + } + } +} \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairFileImplement/Models/Component.cs b/PlumbingRepair/PlumbingRepairFileImplement/Models/Component.cs new file mode 100644 index 0000000..18ff700 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/Models/Component.cs @@ -0,0 +1,66 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Models; +using System.Xml.Linq; + +namespace PlumbingRepairFileImplement.Models +{ + internal class Component : IComponentModel + { + public int Id { get; private set; } + + public string ComponentName { get; private 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())); + } +} \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairFileImplement/Models/Order.cs b/PlumbingRepair/PlumbingRepairFileImplement/Models/Order.cs new file mode 100644 index 0000000..c0217b7 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/Models/Order.cs @@ -0,0 +1,94 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Enums; +using PlumbingRepairDataModels.Models; +using System.Reflection; +using System.Xml.Linq; + +namespace PlumbingRepairFileImplement.Models +{ + internal class Order : IOrderModel + { + public int WorkId { get; private set; } + + public int Count { get; private set; } + + public double Sum { get; private set; } + + public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; + + public DateTime DateCreate { get; private set; } = DateTime.Now; + + public DateTime? DateImplement { get; private set; } + + public int Id { get; private set; } + + public static Order? Create(OrderBindingModel? model) + { + if (model == null) + { + return null; + } + return new Order() + { + WorkId = model.WorkId, + Count = model.Count, + Sum = model.Sum, + Status = model.Status, + DateCreate = model.DateCreate, + DateImplement = model.DateImplement, + Id = model.Id, + }; + } + + public static Order? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Order() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + WorkId = Convert.ToInt32(element.Element("WorkId")!.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), + 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() + { + WorkId = WorkId, + Count = Count, + Sum = Sum, + Status = Status, + DateCreate = DateCreate, + DateImplement = DateImplement, + Id = Id, + }; + + public XElement GetXElement => new( + "Order", + new XAttribute("Id", Id), + new XElement("WorkId", WorkId.ToString()), + new XElement("Count", Count.ToString()), + new XElement("Sum", Sum.ToString()), + new XElement("Status", Status.ToString()), + new XElement("DateCreate", DateCreate.ToString()), + new XElement("DateImplement", DateImplement.ToString()) + ); + } +} diff --git a/PlumbingRepair/PlumbingRepairFileImplement/Models/Work.cs b/PlumbingRepair/PlumbingRepairFileImplement/Models/Work.cs new file mode 100644 index 0000000..8bee2d4 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/Models/Work.cs @@ -0,0 +1,93 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Models; +using System.Xml.Linq; + +namespace PlumbingRepairFileImplement.Models +{ + internal class Work : IWorkModel + { + public int Id { get; private set; } + + public string WorkName { get; private set; } = string.Empty; + + public double Price { get; private set; } + + public Dictionary Components { get; private set; } = new(); + + private Dictionary? _workComponents = null; + + public Dictionary WorkComponents + { + get + { + if (_workComponents == null) + { + var source = DataFileSingleton.GetInstance(); + _workComponents = Components.ToDictionary(x => x.Key, y => ((source.Components.FirstOrDefault(z => z.Id == y.Key) as IComponentModel)!, y.Value)); + } + return _workComponents; + } + } + + public static Work? Create(WorkBindingModel? model) + { + if (model == null) + { + return null; + } + return new Work() + { + Id = model.Id, + WorkName = model.WorkName, + Price = model.Price, + Components = model.WorkComponents.ToDictionary(x => x.Key, x => x.Value.Item2) + }; + } + + public static Work? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Work() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + WorkName = element.Element("WorkName")!.Value, + Price = Convert.ToDouble(element.Element("Price")!.Value), + Components = element.Element("WorkComponents")!.Elements("WorkComponent") + .ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value)) + }; + } + + public void Update(WorkBindingModel? model) + { + if (model == null) + { + return; + } + WorkName = model.WorkName; + Price = model.Price; + Components = model.WorkComponents.ToDictionary(x => x.Key, x => x.Value.Item2); + _workComponents = null; + } + + public WorkViewModel GetViewModel => new() + { + Id = Id, + WorkName = WorkName, + Price = Price, + WorkComponents = WorkComponents + }; + + public XElement GetXElement => new("Work", + new XAttribute("Id", Id), + new XElement("WorkName", WorkName), + new XElement("Price", Price.ToString()), + new XElement("WorkComponents", Components.Select(x => new XElement("WorkComponent", + new XElement("Key", x.Key), + new XElement("Value", x.Value))) + .ToArray())); + } +} diff --git a/PlumbingRepair/PlumbingRepairFileImplement/PlumbingRepairFileImplement.csproj b/PlumbingRepair/PlumbingRepairFileImplement/PlumbingRepairFileImplement.csproj new file mode 100644 index 0000000..d2b8615 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/PlumbingRepairFileImplement.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/PlumbingRepair/PlumbingRepairView/PlumbingRepairView.csproj b/PlumbingRepair/PlumbingRepairView/PlumbingRepairView.csproj index ee2e00f..05e94b0 100644 --- a/PlumbingRepair/PlumbingRepairView/PlumbingRepairView.csproj +++ b/PlumbingRepair/PlumbingRepairView/PlumbingRepairView.csproj @@ -14,6 +14,7 @@ + diff --git a/PlumbingRepair/PlumbingRepairView/Program.cs b/PlumbingRepair/PlumbingRepairView/Program.cs index 03a1750..b77b6db 100644 --- a/PlumbingRepair/PlumbingRepairView/Program.cs +++ b/PlumbingRepair/PlumbingRepairView/Program.cs @@ -4,7 +4,7 @@ using NLog.Extensions.Logging; using PlumbingRepairBusinessLogic.BusinessLogics; using PlumbingRepairContracts.BusinessLogicsContracts; using PlumbingRepairContracts.StoragesContracts; -using PlumbingRepairListImplement.Implements; +using PlumbingRepairFileImplement.Implements; namespace PlumbingRepairView { -- 2.25.1 From 9540dbbfaba93371b6ee1df417012d87630de765 Mon Sep 17 00:00:00 2001 From: sardq Date: Sat, 23 Mar 2024 20:08:44 +0400 Subject: [PATCH 2/3] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PlumbingRepair/PlumbingRepairView/FormMain.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/PlumbingRepair/PlumbingRepairView/FormMain.cs b/PlumbingRepair/PlumbingRepairView/FormMain.cs index e1e6e98..76ec79e 100644 --- a/PlumbingRepair/PlumbingRepairView/FormMain.cs +++ b/PlumbingRepair/PlumbingRepairView/FormMain.cs @@ -30,7 +30,6 @@ namespace PlumbingRepairView if (list != null) { dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; dataGridView.Columns["WorkId"].Visible= false; } _logger.LogInformation("Загрузка заказов"); -- 2.25.1 From 8ead770c88e7fa424cc4d6d8888a594f3a32d15a Mon Sep 17 00:00:00 2001 From: sardq Date: Fri, 12 Apr 2024 20:55:05 +0400 Subject: [PATCH 3/3] =?UTF-8?q?2=20=D1=83=D1=81=D0=BB=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D0=B0=D1=8F=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=D0=BD=D0=B0=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/OrderLogic.cs | 26 +++- .../BusinessLogics/ShopLogic.cs | 73 +++++++++- .../BindingModels/ShopBindingModel.cs | 10 +- .../BusinessLogicsContracts/IShopLogic.cs | 8 ++ .../SearchModels/ShopSearchModel.cs | 8 +- .../StoragesContracts/IShopStorage.cs | 4 + .../ViewModels/ShopViewModel.cs | 2 + .../Models/IShopModel.cs | 2 + .../DataFileSingleton.cs | 5 + .../Implements/ShopStorage.cs | 134 ++++++++++++++++++ .../Models/Shop.cs | 107 ++++++++++++++ .../PlumbingRepairFileImplement.csproj | 4 - .../Implements/ShopStorage.cs | 5 + .../Models/Shop.cs | 10 +- .../PlumbingRepairView/FormMain.Designer.cs | 16 ++- PlumbingRepair/PlumbingRepairView/FormMain.cs | 11 +- .../FormSellWorks.Designer.cs | 126 ++++++++++++++++ .../PlumbingRepairView/FormSellWorks.cs | 87 ++++++++++++ .../PlumbingRepairView/FormSellWorks.resx | 60 ++++++++ .../PlumbingRepairView/FormShop.Designer.cs | 40 ++++-- PlumbingRepair/PlumbingRepairView/FormShop.cs | 11 +- .../FormStoreReplenishment.Designer.cs | 2 +- PlumbingRepair/PlumbingRepairView/Program.cs | 1 + 23 files changed, 720 insertions(+), 32 deletions(-) create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/Implements/ShopStorage.cs create mode 100644 PlumbingRepair/PlumbingRepairFileImplement/Models/Shop.cs create mode 100644 PlumbingRepair/PlumbingRepairView/FormSellWorks.Designer.cs create mode 100644 PlumbingRepair/PlumbingRepairView/FormSellWorks.cs create mode 100644 PlumbingRepair/PlumbingRepairView/FormSellWorks.resx diff --git a/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogics/OrderLogic.cs b/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogics/OrderLogic.cs index 5e0ba7e..c5cdfa8 100644 --- a/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogics/OrderLogic.cs @@ -14,10 +14,16 @@ namespace PlumbingRepairBusinessLogic.BusinessLogics private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + private readonly IShopStorage _shopStorage; + private readonly IWorkStorage _workStorage; + private readonly IShopLogic _shopLogic; + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IShopStorage shopStorage, IWorkStorage workStorage, IShopLogic shopLogic) { _logger = logger; _orderStorage = orderStorage; + _shopStorage = shopStorage; + _workStorage = workStorage; + _shopLogic = shopLogic; } public bool CreateOrder(OrderBindingModel model) { @@ -75,11 +81,21 @@ namespace PlumbingRepairBusinessLogic.BusinessLogics _logger.LogWarning("Change status operation failed"); return false; } + if (newStatus == OrderStatus.Выдан) + { + var work = _workStorage.GetElement(new WorkSearchModel() { Id = viewModel.WorkId}); + if (work == null) + { + _logger.LogWarning("Change status operation failed.Work not found"); + return false; + } + if (!_shopLogic.CheckAndSupply(work, viewModel.Count)) + { + _logger.LogWarning("Change status operation failed. Works delivery operation failed"); + return false; + } + } model.Status = newStatus; - model.WorkId = viewModel.WorkId; - model.Count = viewModel.Count; - model.Sum = viewModel.Sum; - model.DateCreate = viewModel.DateCreate; if (model.Status == OrderStatus.Готов) { model.DateImplement = DateTime.Now; diff --git a/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogics/ShopLogic.cs b/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogics/ShopLogic.cs index 54f2762..ce38d40 100644 --- a/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogics/ShopLogic.cs +++ b/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogics/ShopLogic.cs @@ -5,6 +5,12 @@ using PlumbingRepairContracts.SearchModels; using PlumbingRepairContracts.StoragesContracts; using PlumbingRepairContracts.ViewModels; using PlumbingRepairDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; namespace PlumbingRepairBusinessLogic.BusinessLogics { @@ -101,9 +107,12 @@ namespace PlumbingRepairBusinessLogic.BusinessLogics var element = _shopStorage.GetElement(shopModel); if (element == null) { - throw new InvalidOperationException("StoreReplenishment. Element not found"); + throw new InvalidOperationException("Ошибка. Элемент не найден"); + } + if(element.maxCountWorks - element.ShopWorks.Sum(x => x.Value.Item2) < count) + { + throw new InvalidOperationException("Ошибка. Нет места в магазине"); } - if(element.ShopWorks.ContainsKey(workModel.Id)) { var oldWorks = element.ShopWorks[workModel.Id]; @@ -122,7 +131,8 @@ namespace PlumbingRepairBusinessLogic.BusinessLogics ShopName = element.ShopName, Address = element.Address, DateOpening = element.DateOpening, - ShopWorks= element.ShopWorks + maxCountWorks = element.maxCountWorks, + ShopWorks= element.ShopWorks, }) == null) { _logger.LogInformation("StoreReplenishment. Update operation failed"); @@ -132,6 +142,54 @@ namespace PlumbingRepairBusinessLogic.BusinessLogics } + public bool CheckAndSupply(IWorkModel model, int count) + { + if (count<0) + { + _logger.LogWarning("Checksupply operation error. Works count < 0."); + return false; + } + var shopList = _shopStorage.GetFullList(); + int shopsCapacity = shopList.Sum(x => x.maxCountWorks); + int currentWorks = shopList.Select(x => x.ShopWorks.Sum(x => x.Value.Item2)).Sum(); + int freespace = shopsCapacity - currentWorks; + if ( freespace < count) + { + _logger.LogWarning("Checksupply operation error. No space for a new work."); + return false; + } + foreach (var shop in shopList) + { + int freePlaces = shop.maxCountWorks - shop.ShopWorks.Select(x => x.Value.Item2).Sum(); + if (freePlaces == 0) + { + continue; + } + if( freePlaces - count >= 0) + { + if (StoreReplenishment(new() { Id = shop.Id }, model, count)) + count = 0; + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + if (freePlaces - count < 0) + { + if (StoreReplenishment(new() { Id = shop.Id }, model, freePlaces)) + count-= freePlaces; + else + { + _logger.LogWarning("Supply error"); + return false; + } + } + if (count == 0) + return true; + } + return false; + } private void CheckModel(ShopBindingModel model, bool withParams = true) { if (model == null) @@ -150,7 +208,10 @@ namespace PlumbingRepairBusinessLogic.BusinessLogics { throw new ArgumentNullException("Нет адреса магазина", nameof(model.ShopName)); } - + if (model.maxCountWorks < 0) + { + throw new InvalidOperationException("Максимальное количество работ магазина отрицательно"); + } _logger.LogInformation("Shop. ShopName:{ShopName}. Address:{Address}. Id:{Id}", model.ShopName, model.Address, model.Id); var element = _shopStorage.GetElement(new ShopSearchModel { @@ -161,5 +222,9 @@ namespace PlumbingRepairBusinessLogic.BusinessLogics throw new InvalidOperationException("Компонент с таким названием уже есть"); } } + public bool SellWork(IWorkModel model, int count) + { + return _shopStorage.SellWork(model, count); + } } } diff --git a/PlumbingRepair/PlumbingRepairContracts/BindingModels/ShopBindingModel.cs b/PlumbingRepair/PlumbingRepairContracts/BindingModels/ShopBindingModel.cs index 14fffbe..37d3ea7 100644 --- a/PlumbingRepair/PlumbingRepairContracts/BindingModels/ShopBindingModel.cs +++ b/PlumbingRepair/PlumbingRepairContracts/BindingModels/ShopBindingModel.cs @@ -1,4 +1,10 @@ -using PlumbingRepairDataModels.Models; +using PlumbingRepairDataModels.Enums; +using PlumbingRepairDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; namespace PlumbingRepairContracts.BindingModels { @@ -10,6 +16,8 @@ namespace PlumbingRepairContracts.BindingModels public string Address { get; set; } = string.Empty; + public int maxCountWorks { get; set; } + public DateTime DateOpening { get; set; } = DateTime.Now; public Dictionary ShopWorks { get; set; } = new(); diff --git a/PlumbingRepair/PlumbingRepairContracts/BusinessLogicsContracts/IShopLogic.cs b/PlumbingRepair/PlumbingRepairContracts/BusinessLogicsContracts/IShopLogic.cs index fd54ec4..3043feb 100644 --- a/PlumbingRepair/PlumbingRepairContracts/BusinessLogicsContracts/IShopLogic.cs +++ b/PlumbingRepair/PlumbingRepairContracts/BusinessLogicsContracts/IShopLogic.cs @@ -2,6 +2,11 @@ using PlumbingRepairContracts.SearchModels; using PlumbingRepairContracts.ViewModels; using PlumbingRepairDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; namespace PlumbingRepairContracts.BusinessLogicsContracts { @@ -18,5 +23,8 @@ namespace PlumbingRepairContracts.BusinessLogicsContracts bool Delete(ShopBindingModel model); bool StoreReplenishment(ShopSearchModel shopModel, IWorkModel workModel, int count); + + bool SellWork(IWorkModel workModel, int count); + bool CheckAndSupply(IWorkModel workModel, int count); } } diff --git a/PlumbingRepair/PlumbingRepairContracts/SearchModels/ShopSearchModel.cs b/PlumbingRepair/PlumbingRepairContracts/SearchModels/ShopSearchModel.cs index 9e730c0..a64ba27 100644 --- a/PlumbingRepair/PlumbingRepairContracts/SearchModels/ShopSearchModel.cs +++ b/PlumbingRepair/PlumbingRepairContracts/SearchModels/ShopSearchModel.cs @@ -1,4 +1,10 @@ -namespace PlumbingRepairContracts.SearchModels +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PlumbingRepairContracts.SearchModels { public class ShopSearchModel { diff --git a/PlumbingRepair/PlumbingRepairContracts/StoragesContracts/IShopStorage.cs b/PlumbingRepair/PlumbingRepairContracts/StoragesContracts/IShopStorage.cs index e9d4ffc..ee0d3bd 100644 --- a/PlumbingRepair/PlumbingRepairContracts/StoragesContracts/IShopStorage.cs +++ b/PlumbingRepair/PlumbingRepairContracts/StoragesContracts/IShopStorage.cs @@ -1,6 +1,7 @@ using PlumbingRepairContracts.BindingModels; using PlumbingRepairContracts.SearchModels; using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Models; namespace PlumbingRepairContracts.StoragesContracts { @@ -17,5 +18,8 @@ namespace PlumbingRepairContracts.StoragesContracts ShopViewModel? Update(ShopBindingModel model); ShopViewModel? Delete(ShopBindingModel model); + + bool SellWork(IWorkModel workModel, int count); + } } diff --git a/PlumbingRepair/PlumbingRepairContracts/ViewModels/ShopViewModel.cs b/PlumbingRepair/PlumbingRepairContracts/ViewModels/ShopViewModel.cs index 9e10421..f673997 100644 --- a/PlumbingRepair/PlumbingRepairContracts/ViewModels/ShopViewModel.cs +++ b/PlumbingRepair/PlumbingRepairContracts/ViewModels/ShopViewModel.cs @@ -12,6 +12,8 @@ namespace PlumbingRepairContracts.ViewModels [DisplayName("Адрес")] public string Address { get; set; } = string.Empty; + [DisplayName("Максимальное количество работ")] + public int maxCountWorks { get; set; } [DisplayName("Дата открытия")] public DateTime DateOpening { get; set; } public Dictionary ShopWorks { get; set; } = new(); diff --git a/PlumbingRepair/PlumbingRepairDataModels/Models/IShopModel.cs b/PlumbingRepair/PlumbingRepairDataModels/Models/IShopModel.cs index 9a6add5..55197c1 100644 --- a/PlumbingRepair/PlumbingRepairDataModels/Models/IShopModel.cs +++ b/PlumbingRepair/PlumbingRepairDataModels/Models/IShopModel.cs @@ -8,6 +8,8 @@ DateTime DateOpening { get; } + int maxCountWorks { get; } + Dictionary ShopWorks { get; } } } diff --git a/PlumbingRepair/PlumbingRepairFileImplement/DataFileSingleton.cs b/PlumbingRepair/PlumbingRepairFileImplement/DataFileSingleton.cs index 10d3e85..2a6c3d0 100644 --- a/PlumbingRepair/PlumbingRepairFileImplement/DataFileSingleton.cs +++ b/PlumbingRepair/PlumbingRepairFileImplement/DataFileSingleton.cs @@ -13,11 +13,14 @@ namespace PlumbingRepairFileImplement private readonly string WorkFileName = "Work.xml"; + private readonly string ShopFileName = "Shop.xml"; + public List Components { get; private set; } public List Orders { get; private set; } public List Works { get; private set; } + public List Shops { get; private set; } public static DataFileSingleton GetInstance() { @@ -33,12 +36,14 @@ namespace PlumbingRepairFileImplement public void SaveWorks() => SaveData(Works, WorkFileName, "Works", 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)!)!; Works = LoadData(WorkFileName, "Work", x => Work.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/PlumbingRepair/PlumbingRepairFileImplement/Implements/ShopStorage.cs b/PlumbingRepair/PlumbingRepairFileImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..e540b4b --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/Implements/ShopStorage.cs @@ -0,0 +1,134 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.StoragesContracts; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Models; +using PlumbingRepairFileImplement.Models; + +namespace PlumbingRepairFileImplement.Implements +{ + public class ShopStorage : IShopStorage + { + private readonly DataFileSingleton source; + + public ShopStorage() + { + source = DataFileSingleton.GetInstance(); + } + + public List GetFullList() + { + return source.Shops + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName)) + { + return new(); + } + return source.Shops + .Where(x => x.ShopName.Contains(model.ShopName)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue) + { + return null; + } + return source.Shops + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) && x.ShopName == model.ShopName) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + model.Id = source.Shops.Count > 0 ? source.Shops.Max(x => x.Id) + 1 : 1; + var newShop = Shop.Create(model); + if (newShop == null) + { + return null; + } + source.Shops.Add(newShop); + source.SaveShops(); + return newShop.GetViewModel; + } + + public ShopViewModel? Update(ShopBindingModel model) + { + var component = source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (component == null) + { + return null; + } + component.Update(model); + source.SaveShops(); + return component.GetViewModel; + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + var element = source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + source.Shops.Remove(element); + source.SaveShops(); + return element.GetViewModel; + } + return null; + } + + public bool SellWork(IWorkModel model, int count) + { + var work = source.Works.FirstOrDefault(x => x.Id == model.Id); + int countInShops = source.Shops + .SelectMany(x => x.ShopWorks) + .Sum(y => y.Key == model.Id ? y.Value.Item2 : 0); + + if (work == null || countInShops < count) + { + return false; + } + + foreach (var shop in source.Shops) + { + var shopWorks = shop.ShopWorks.Where(x => x.Key == model.Id); + if (shopWorks.Any()) + { + var shopWork = shopWorks.First(); + int min = Math.Min(shopWork.Value.Item2, count); + if (min == shopWork.Value.Item2) + { + shop.ShopWorks.Remove(shopWork.Key); + } + else + { + shop.ShopWorks[shopWork.Key] = (shopWork.Value.Item1, shopWork.Value.Item2 - min); + } + shop.Update(new ShopBindingModel + { + Id = shop.Id, + ShopName = shop.ShopName, + Address = shop.Address, + DateOpening = shop.DateOpening, + ShopWorks = shop.ShopWorks, + maxCountWorks = shop.maxCountWorks + }); + count -= min; + if (count <= 0) + { + break; + } + } + } + source.SaveShops(); + return true; + } + } +} \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairFileImplement/Models/Shop.cs b/PlumbingRepair/PlumbingRepairFileImplement/Models/Shop.cs new file mode 100644 index 0000000..6620ee0 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairFileImplement/Models/Shop.cs @@ -0,0 +1,107 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Models; +using System.Xml.Linq; + +namespace PlumbingRepairFileImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + + public string ShopName { get; private set; } = string.Empty; + public string Address { get; private set; } = string.Empty; + + public DateTime DateOpening { get; private set; } + + public Dictionary Works { get; private set; } = new(); + + private Dictionary? _shopWorks = null; + public Dictionary ShopWorks + { + get + { + if (_shopWorks == null) + { + var source = DataFileSingleton.GetInstance(); + _shopWorks = Works.ToDictionary(x => x.Key, + y => ((source.Works.FirstOrDefault(z => z.Id == y.Key) as IWorkModel)!, y.Value)); + } + return _shopWorks; + } + } + + public int maxCountWorks { get; private set; } + + + public static Shop? Create(ShopBindingModel model) + { + if (model == null) + { + return null; + } + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOpening = model.DateOpening, + Works = model.ShopWorks.ToDictionary(x => x.Key, x => x.Value.Item2), + maxCountWorks= model.maxCountWorks, + }; + } + + 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, + DateOpening = Convert.ToDateTime(element.Element("DateOpening")!.Value), + maxCountWorks = Convert.ToInt32(element.Element("maxCountWorks")!.Value), + Works = element.Element("ShopWorks")!.Elements("ShopWork") + .ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value)) + }; + } + + public void Update(ShopBindingModel model) + { + if (model == null) + { + return; + } + ShopName = model.ShopName; + Address = model.Address; + DateOpening = model.DateOpening; + Works = model.ShopWorks.ToDictionary(x => x.Key, x => x.Value.Item2); + maxCountWorks = model.maxCountWorks; + _shopWorks = null; + } + + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpening = DateOpening, + ShopWorks = ShopWorks, + maxCountWorks = maxCountWorks, + }; + + public XElement GetXElement => new("Shop", + new XAttribute("Id", Id), + new XElement("ShopName", ShopName), + new XElement("Address", Address), + new XElement("DateOpening", DateOpening.ToString()), + new XElement("maxCountWorks", maxCountWorks.ToString()), + new XElement("ShopWorks", + Works.Select(x => new XElement("ShopWork", + new XElement("Key", x.Key), + new XElement("Value", x.Value))).ToArray())); + } +} \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairFileImplement/PlumbingRepairFileImplement.csproj b/PlumbingRepair/PlumbingRepairFileImplement/PlumbingRepairFileImplement.csproj index d2b8615..05f8377 100644 --- a/PlumbingRepair/PlumbingRepairFileImplement/PlumbingRepairFileImplement.csproj +++ b/PlumbingRepair/PlumbingRepairFileImplement/PlumbingRepairFileImplement.csproj @@ -11,8 +11,4 @@ - - - - diff --git a/PlumbingRepair/PlumbingRepairListImplement/Implements/ShopStorage.cs b/PlumbingRepair/PlumbingRepairListImplement/Implements/ShopStorage.cs index 750f879..be1f099 100644 --- a/PlumbingRepair/PlumbingRepairListImplement/Implements/ShopStorage.cs +++ b/PlumbingRepair/PlumbingRepairListImplement/Implements/ShopStorage.cs @@ -2,6 +2,7 @@ using PlumbingRepairContracts.SearchModels; using PlumbingRepairContracts.StoragesContracts; using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Models; using PlumbingRepairListImplement.Models; using System; using System.Collections.Generic; @@ -104,5 +105,9 @@ namespace PlumbingRepairListImplement.Implements } return null; } + public bool SellWork(IWorkModel model, int count) + { + throw new NotImplementedException(); + } } } diff --git a/PlumbingRepair/PlumbingRepairListImplement/Models/Shop.cs b/PlumbingRepair/PlumbingRepairListImplement/Models/Shop.cs index b843322..45c2122 100644 --- a/PlumbingRepair/PlumbingRepairListImplement/Models/Shop.cs +++ b/PlumbingRepair/PlumbingRepairListImplement/Models/Shop.cs @@ -15,6 +15,8 @@ namespace PlumbingRepairListImplement.Models public Dictionary ShopWorks { get; private set; } = new Dictionary(); + public int maxCountWorks { get; private set; } + public static Shop? Create(ShopBindingModel? model) { if (model == null) @@ -27,7 +29,8 @@ namespace PlumbingRepairListImplement.Models ShopName = model.ShopName, Address = model.Address, DateOpening = model.DateOpening, - ShopWorks = model.ShopWorks + ShopWorks = model.ShopWorks, + maxCountWorks = model.maxCountWorks }; } @@ -40,6 +43,8 @@ namespace PlumbingRepairListImplement.Models ShopName = model.ShopName; Address = model.Address; DateOpening= model.DateOpening; + ShopWorks= model.ShopWorks; + maxCountWorks= model.maxCountWorks; } public ShopViewModel GetViewModel => new() @@ -48,7 +53,8 @@ namespace PlumbingRepairListImplement.Models ShopName = ShopName, Address = Address, DateOpening = DateOpening, - ShopWorks = ShopWorks + ShopWorks = ShopWorks, + maxCountWorks = maxCountWorks }; } } diff --git a/PlumbingRepair/PlumbingRepairView/FormMain.Designer.cs b/PlumbingRepair/PlumbingRepairView/FormMain.Designer.cs index 80c1cec..bb6395b 100644 --- a/PlumbingRepair/PlumbingRepairView/FormMain.Designer.cs +++ b/PlumbingRepair/PlumbingRepairView/FormMain.Designer.cs @@ -40,6 +40,7 @@ this.РаботыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.магазиныToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.пToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.продажаРаботToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.menuStrip1.SuspendLayout(); this.SuspendLayout(); @@ -141,7 +142,8 @@ this.компонентыToolStripMenuItem, this.РаботыToolStripMenuItem, this.магазиныToolStripMenuItem, - this.пToolStripMenuItem}); + this.пToolStripMenuItem, + this.продажаРаботToolStripMenuItem}); this.справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem"; this.справочникиToolStripMenuItem.Size = new System.Drawing.Size(139, 29); this.справочникиToolStripMenuItem.Text = "Справочники"; @@ -149,14 +151,14 @@ // компонентыToolStripMenuItem // this.компонентыToolStripMenuItem.Name = "компонентыToolStripMenuItem"; - this.компонентыToolStripMenuItem.Size = new System.Drawing.Size(218, 34); + this.компонентыToolStripMenuItem.Size = new System.Drawing.Size(296, 34); this.компонентыToolStripMenuItem.Text = "Компоненты"; this.компонентыToolStripMenuItem.Click += new System.EventHandler(this.КомпонентыToolStripMenuItem_Click); // // РаботыToolStripMenuItem // this.РаботыToolStripMenuItem.Name = "РаботыToolStripMenuItem"; - this.РаботыToolStripMenuItem.Size = new System.Drawing.Size(218, 34); + this.РаботыToolStripMenuItem.Size = new System.Drawing.Size(296, 34); this.РаботыToolStripMenuItem.Text = "Работы"; this.РаботыToolStripMenuItem.Click += new System.EventHandler(this.РаботыToolStripMenuItem_Click); // @@ -174,6 +176,13 @@ this.пToolStripMenuItem.Text = "Пополнение магазина"; this.пToolStripMenuItem.Click += new System.EventHandler(this.пополнениеToolStripMenuItem_Click); // + // продажаРаботToolStripMenuItem + // + this.продажаРаботToolStripMenuItem.Name = "продажаРаботToolStripMenuItem"; + this.продажаРаботToolStripMenuItem.Size = new System.Drawing.Size(296, 34); + this.продажаРаботToolStripMenuItem.Text = "Продажа работ"; + this.продажаРаботToolStripMenuItem.Click += new System.EventHandler(this.продажаРаботToolStripMenuItem_Click); + // // FormMain // this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F); @@ -212,5 +221,6 @@ private ToolStripMenuItem РаботыToolStripMenuItem; private ToolStripMenuItem магазиныToolStripMenuItem; private ToolStripMenuItem пToolStripMenuItem; + private ToolStripMenuItem продажаРаботToolStripMenuItem; } } \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairView/FormMain.cs b/PlumbingRepair/PlumbingRepairView/FormMain.cs index 91fa707..84fcc44 100644 --- a/PlumbingRepair/PlumbingRepairView/FormMain.cs +++ b/PlumbingRepair/PlumbingRepairView/FormMain.cs @@ -158,6 +158,15 @@ namespace PlumbingRepairView private void ButtonRef_Click(object sender, EventArgs e) { LoadData(); - } + } + + private void продажаРаботToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormSellWorks)); + if (service is FormSellWorks form) + { + form.ShowDialog(); + } + } } } \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairView/FormSellWorks.Designer.cs b/PlumbingRepair/PlumbingRepairView/FormSellWorks.Designer.cs new file mode 100644 index 0000000..bdaeb44 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairView/FormSellWorks.Designer.cs @@ -0,0 +1,126 @@ +namespace PlumbingRepairView +{ + partial class FormSellWorks + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.textBoxCount = new System.Windows.Forms.TextBox(); + this.labelCount = new System.Windows.Forms.Label(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.buttonSell = new System.Windows.Forms.Button(); + this.comboBoxWork = new System.Windows.Forms.ComboBox(); + this.labelWork = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // textBoxCount + // + this.textBoxCount.Location = new System.Drawing.Point(137, 103); + this.textBoxCount.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5); + this.textBoxCount.Name = "textBoxCount"; + this.textBoxCount.Size = new System.Drawing.Size(183, 31); + this.textBoxCount.TabIndex = 13; + // + // labelCount + // + this.labelCount.AutoSize = true; + this.labelCount.Location = new System.Drawing.Point(14, 103); + this.labelCount.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.labelCount.Name = "labelCount"; + this.labelCount.Size = new System.Drawing.Size(111, 25); + this.labelCount.TabIndex = 12; + this.labelCount.Text = "Количество:"; + // + // buttonCancel + // + this.buttonCancel.Location = new System.Drawing.Point(361, 156); + this.buttonCancel.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(126, 45); + this.buttonCancel.TabIndex = 15; + this.buttonCancel.Text = "Отмена"; + this.buttonCancel.UseVisualStyleBackColor = true; + this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); + // + // buttonSell + // + this.buttonSell.Location = new System.Drawing.Point(225, 156); + this.buttonSell.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5); + this.buttonSell.Name = "buttonSell"; + this.buttonSell.Size = new System.Drawing.Size(126, 45); + this.buttonSell.TabIndex = 14; + this.buttonSell.Text = "Продать"; + this.buttonSell.UseVisualStyleBackColor = true; + this.buttonSell.Click += new System.EventHandler(this.ButtonSale_Click); + // + // comboBoxWork + // + this.comboBoxWork.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxWork.FormattingEnabled = true; + this.comboBoxWork.Location = new System.Drawing.Point(137, 33); + this.comboBoxWork.Name = "comboBoxWork"; + this.comboBoxWork.Size = new System.Drawing.Size(317, 33); + this.comboBoxWork.TabIndex = 16; + // + // labelWork + // + this.labelWork.AutoSize = true; + this.labelWork.Location = new System.Drawing.Point(14, 36); + this.labelWork.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.labelWork.Name = "labelWork"; + this.labelWork.Size = new System.Drawing.Size(72, 25); + this.labelWork.TabIndex = 17; + this.labelWork.Text = "Работа:"; + // + // FormSellWorks + // + this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(493, 207); + this.Controls.Add(this.labelWork); + this.Controls.Add(this.comboBoxWork); + this.Controls.Add(this.textBoxCount); + this.Controls.Add(this.labelCount); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonSell); + this.Name = "FormSellWorks"; + this.Text = "Продажа работ"; + this.Load += new System.EventHandler(this.FormSellWorks_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private TextBox textBoxCount; + private Label labelCount; + private Button buttonCancel; + private Button buttonSell; + private ComboBox comboBoxWork; + private Label labelWork; + } +} \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairView/FormSellWorks.cs b/PlumbingRepair/PlumbingRepairView/FormSellWorks.cs new file mode 100644 index 0000000..a56613e --- /dev/null +++ b/PlumbingRepair/PlumbingRepairView/FormSellWorks.cs @@ -0,0 +1,87 @@ +using Microsoft.Extensions.Logging; +using PlumbingRepairContracts.BusinessLogicsContracts; +using PlumbingRepairContracts.BindingModels; + +namespace PlumbingRepairView +{ + public partial class FormSellWorks : Form + { + private readonly ILogger _logger; + + private readonly IWorkLogic _workLogic; + + private readonly IShopLogic _logicShop; + + public FormSellWorks(ILogger logger, IWorkLogic workLogic, IShopLogic logicShop) + { + InitializeComponent(); + _logger = logger; + _workLogic = workLogic; + _logicShop = logicShop; + } + + private void FormSellWorks_Load(object sender, EventArgs e) + { + _logger.LogInformation("Ice creams loading"); + try + { + var list = _workLogic.ReadList(null); + if (list != null) + { + comboBoxWork.DisplayMember = "WorkName"; + comboBoxWork.ValueMember = "Id"; + comboBoxWork.DataSource = list; + comboBoxWork.SelectedItem = null; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Works loading error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonSale_Click(object sender, EventArgs e) + { + if (comboBoxWork.SelectedValue == null) + { + MessageBox.Show("Выберите работу", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (string.IsNullOrEmpty(textBoxCount.Text)) + { + MessageBox.Show("Заполните поле Количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("work sale"); + try + { + var operationResult = _logicShop.SellWork( + new WorkBindingModel + { + Id = Convert.ToInt32(comboBoxWork.SelectedValue) + }, + Convert.ToInt32(textBoxCount.Text) + ); + if (!operationResult) + { + throw new Exception("Ошибка при продаже."); + } + MessageBox.Show("Продажа прошла успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + DialogResult = DialogResult.OK; + Close(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Work sale error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairView/FormSellWorks.resx b/PlumbingRepair/PlumbingRepairView/FormSellWorks.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/PlumbingRepair/PlumbingRepairView/FormSellWorks.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairView/FormShop.Designer.cs b/PlumbingRepair/PlumbingRepairView/FormShop.Designer.cs index a65a88d..d96e117 100644 --- a/PlumbingRepair/PlumbingRepairView/FormShop.Designer.cs +++ b/PlumbingRepair/PlumbingRepairView/FormShop.Designer.cs @@ -41,13 +41,15 @@ this.ColumnName = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.ColumnCount = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.labelDateOpening = new System.Windows.Forms.Label(); + this.textBoxMaxCount = new System.Windows.Forms.TextBox(); + this.labelMaxCount = new System.Windows.Forms.Label(); this.groupBoxComponents.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.SuspendLayout(); // // textBoxAddress // - this.textBoxAddress.Location = new System.Drawing.Point(152, 75); + this.textBoxAddress.Location = new System.Drawing.Point(310, 49); this.textBoxAddress.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5); this.textBoxAddress.Name = "textBoxAddress"; this.textBoxAddress.Size = new System.Drawing.Size(183, 31); @@ -56,7 +58,7 @@ // labelAddress // this.labelAddress.AutoSize = true; - this.labelAddress.Location = new System.Drawing.Point(8, 78); + this.labelAddress.Location = new System.Drawing.Point(8, 52); this.labelAddress.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); this.labelAddress.Name = "labelAddress"; this.labelAddress.Size = new System.Drawing.Size(66, 25); @@ -87,7 +89,7 @@ // // textBoxName // - this.textBoxName.Location = new System.Drawing.Point(152, 27); + this.textBoxName.Location = new System.Drawing.Point(310, 1); this.textBoxName.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5); this.textBoxName.Name = "textBoxName"; this.textBoxName.Size = new System.Drawing.Size(358, 31); @@ -96,7 +98,7 @@ // labelName // this.labelName.AutoSize = true; - this.labelName.Location = new System.Drawing.Point(8, 30); + this.labelName.Location = new System.Drawing.Point(8, 7); this.labelName.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); this.labelName.Name = "labelName"; this.labelName.Size = new System.Drawing.Size(94, 25); @@ -105,7 +107,7 @@ // // dateTimePickerOpening // - this.dateTimePickerOpening.Location = new System.Drawing.Point(152, 118); + this.dateTimePickerOpening.Location = new System.Drawing.Point(152, 133); this.dateTimePickerOpening.Name = "dateTimePickerOpening"; this.dateTimePickerOpening.Size = new System.Drawing.Size(300, 31); this.dateTimePickerOpening.TabIndex = 18; @@ -115,7 +117,7 @@ this.groupBoxComponents.Controls.Add(this.dataGridView); this.groupBoxComponents.Controls.Add(this.buttonSave); this.groupBoxComponents.Controls.Add(this.buttonCancel); - this.groupBoxComponents.Location = new System.Drawing.Point(8, 151); + this.groupBoxComponents.Location = new System.Drawing.Point(8, 183); this.groupBoxComponents.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5); this.groupBoxComponents.Name = "groupBoxComponents"; this.groupBoxComponents.Padding = new System.Windows.Forms.Padding(6, 5, 6, 5); @@ -174,18 +176,38 @@ // labelDateOpening // this.labelDateOpening.AutoSize = true; - this.labelDateOpening.Location = new System.Drawing.Point(8, 118); + this.labelDateOpening.Location = new System.Drawing.Point(8, 133); this.labelDateOpening.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); this.labelDateOpening.Name = "labelDateOpening"; this.labelDateOpening.Size = new System.Drawing.Size(135, 25); this.labelDateOpening.TabIndex = 20; this.labelDateOpening.Text = "Дата открытия:"; // + // textBoxMaxCount + // + this.textBoxMaxCount.Location = new System.Drawing.Point(310, 94); + this.textBoxMaxCount.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5); + this.textBoxMaxCount.Name = "textBoxMaxCount"; + this.textBoxMaxCount.Size = new System.Drawing.Size(183, 31); + this.textBoxMaxCount.TabIndex = 22; + // + // labelMaxCount + // + this.labelMaxCount.AutoSize = true; + this.labelMaxCount.Location = new System.Drawing.Point(8, 93); + this.labelMaxCount.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.labelMaxCount.Name = "labelMaxCount"; + this.labelMaxCount.Size = new System.Drawing.Size(290, 25); + this.labelMaxCount.TabIndex = 21; + this.labelMaxCount.Text = "Максимальное количество работ:"; + // // FormShop // this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(812, 543); + this.ClientSize = new System.Drawing.Size(812, 564); + this.Controls.Add(this.textBoxMaxCount); + this.Controls.Add(this.labelMaxCount); this.Controls.Add(this.labelDateOpening); this.Controls.Add(this.groupBoxComponents); this.Controls.Add(this.dateTimePickerOpening); @@ -218,5 +240,7 @@ private DataGridViewTextBoxColumn ColumnName; private DataGridViewTextBoxColumn ColumnCount; private Label labelDateOpening; + private TextBox textBoxMaxCount; + private Label labelMaxCount; } } \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairView/FormShop.cs b/PlumbingRepair/PlumbingRepairView/FormShop.cs index f610272..fe0427a 100644 --- a/PlumbingRepair/PlumbingRepairView/FormShop.cs +++ b/PlumbingRepair/PlumbingRepairView/FormShop.cs @@ -27,7 +27,7 @@ namespace PlumbingRepairView } private void FormShop_Load(object sender, EventArgs e) - { + { if (_id.HasValue) { _logger.LogInformation("Загрузка изделия"); @@ -38,6 +38,7 @@ namespace PlumbingRepairView { textBoxName.Text = view.ShopName; textBoxAddress.Text = view.Address; + textBoxMaxCount.Text = view.maxCountWorks.ToString(); dateTimePickerOpening.Value = view.DateOpening; _shopWorks = view.ShopWorks ?? new Dictionary(); LoadData(); @@ -67,7 +68,7 @@ namespace PlumbingRepairView } catch (Exception ex) { - _logger.LogError(ex, "Ошибка загрузки компонент изделия"); + _logger.LogError(ex, "Ошибка загрузки работ магазина"); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } } @@ -83,6 +84,11 @@ namespace PlumbingRepairView MessageBox.Show("Заполните адрес", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } + if (string.IsNullOrEmpty(textBoxMaxCount.Text)) + { + MessageBox.Show("Заполните максимальное количество работ", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } if (string.IsNullOrEmpty(dateTimePickerOpening.Text)) { MessageBox.Show("Заполните дату", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -97,6 +103,7 @@ namespace PlumbingRepairView ShopName = textBoxName.Text, Address = textBoxAddress.Text, DateOpening= dateTimePickerOpening.Value, + maxCountWorks = Convert.ToInt32(textBoxMaxCount.Text), ShopWorks = _shopWorks }; var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model); diff --git a/PlumbingRepair/PlumbingRepairView/FormStoreReplenishment.Designer.cs b/PlumbingRepair/PlumbingRepairView/FormStoreReplenishment.Designer.cs index e6323b8..660c314 100644 --- a/PlumbingRepair/PlumbingRepairView/FormStoreReplenishment.Designer.cs +++ b/PlumbingRepair/PlumbingRepairView/FormStoreReplenishment.Designer.cs @@ -132,7 +132,7 @@ this.Controls.Add(this.labelWorkName); this.Controls.Add(this.labelShopName); this.Name = "FormStoreReplenishment"; - this.Text = "FormStoreReplenishment"; + this.Text = "Пополнение магазина"; this.Load += new System.EventHandler(this.FormStoreReplenishment_Load); this.ResumeLayout(false); this.PerformLayout(); diff --git a/PlumbingRepair/PlumbingRepairView/Program.cs b/PlumbingRepair/PlumbingRepairView/Program.cs index e647003..200a7ad 100644 --- a/PlumbingRepair/PlumbingRepairView/Program.cs +++ b/PlumbingRepair/PlumbingRepairView/Program.cs @@ -55,6 +55,7 @@ namespace PlumbingRepairView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file -- 2.25.1