From 0c7dde6b54c7ff10dd645f6cda81133a82de5ada Mon Sep 17 00:00:00 2001 From: malimova Date: Thu, 15 Feb 2024 23:43:28 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D1=8B=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D1=8B?= =?UTF-8?q?=20ConfectioneryBusinessLoguc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Confectionery/Confectionery.sln | 6 + .../Confectionery/Confectionery.csproj | 4 + .../ComponentLogic.cs | 106 +++++++++++++++ .../ConfectioneryBusinessLogic.csproj | 17 +++ .../ConfectioneryBusinessLogic/OrderLogic.cs | 125 ++++++++++++++++++ .../ConfectioneryBusinessLogic/PastryLogic.cs | 113 ++++++++++++++++ .../ConfectioneryContracts.csproj | 4 + .../StoragesContracts/IPastryStorage.cs | 2 +- .../ConfectioneryDataModels.csproj | 4 + 9 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 Confectionery/ConfectioneryBusinessLogic/ComponentLogic.cs create mode 100644 Confectionery/ConfectioneryBusinessLogic/ConfectioneryBusinessLogic.csproj create mode 100644 Confectionery/ConfectioneryBusinessLogic/OrderLogic.cs create mode 100644 Confectionery/ConfectioneryBusinessLogic/PastryLogic.cs diff --git a/Confectionery/Confectionery.sln b/Confectionery/Confectionery.sln index e0c039f..1097f78 100644 --- a/Confectionery/Confectionery.sln +++ b/Confectionery/Confectionery.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryDataModels", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryContracts", "ConfectioneryContracts\ConfectioneryContracts.csproj", "{6FFC8BF0-172F-4A99-AF4E-8FCEC210FF36}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryBusinessLogic", "ConfectioneryBusinessLogic\ConfectioneryBusinessLogic.csproj", "{A8B0F9F7-FBAA-41C1-A211-DAA3685C9F4E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +29,10 @@ Global {6FFC8BF0-172F-4A99-AF4E-8FCEC210FF36}.Debug|Any CPU.Build.0 = Debug|Any CPU {6FFC8BF0-172F-4A99-AF4E-8FCEC210FF36}.Release|Any CPU.ActiveCfg = Release|Any CPU {6FFC8BF0-172F-4A99-AF4E-8FCEC210FF36}.Release|Any CPU.Build.0 = Release|Any CPU + {A8B0F9F7-FBAA-41C1-A211-DAA3685C9F4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8B0F9F7-FBAA-41C1-A211-DAA3685C9F4E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8B0F9F7-FBAA-41C1-A211-DAA3685C9F4E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A8B0F9F7-FBAA-41C1-A211-DAA3685C9F4E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Confectionery/Confectionery/Confectionery.csproj b/Confectionery/Confectionery/Confectionery.csproj index b57c89e..c939607 100644 --- a/Confectionery/Confectionery/Confectionery.csproj +++ b/Confectionery/Confectionery/Confectionery.csproj @@ -8,4 +8,8 @@ enable + + + + \ No newline at end of file diff --git a/Confectionery/ConfectioneryBusinessLogic/ComponentLogic.cs b/Confectionery/ConfectioneryBusinessLogic/ComponentLogic.cs new file mode 100644 index 0000000..fc5f458 --- /dev/null +++ b/Confectionery/ConfectioneryBusinessLogic/ComponentLogic.cs @@ -0,0 +1,106 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryContracts.ViewModels; +using Microsoft.Extensions.Logging; + +namespace ConfectioneryBusinessLogic +{ + public class ComponentLogic : IComponentLogic + { + private readonly ILogger _logger; + private readonly IComponentStorage _componentStorage; + public ComponentLogic(ILogger logger, IComponentStorage componentStorage) + { + _logger = logger; + _componentStorage = componentStorage; + } + public List? ReadList(ComponentSearchModel? model) + { + _logger.LogInformation("ReadList. ComponentName:{ComponentName}. Id:{ Id}", model?.ComponentName, model?.Id); + var list = model == null ? _componentStorage.GetFullList() : _componentStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + public ComponentViewModel? ReadElement(ComponentSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ComponentName:{ComponentName}. Id:{ Id}", model.ComponentName, model.Id); + var element = _componentStorage.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(ComponentBindingModel model) + { + CheckModel(model); + if (_componentStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + public bool Update(ComponentBindingModel model) + { + CheckModel(model); + if (_componentStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + public bool Delete(ComponentBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_componentStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + private void CheckModel(ComponentBindingModel model, bool withParams = + true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.ComponentName)) + { + throw new ArgumentNullException("Нет названия компонента", + nameof(model.ComponentName)); + } + if (model.Cost <= 0) + { + throw new ArgumentNullException("Цена компонента должна быть больше 0", nameof(model.Cost)); + } + _logger.LogInformation("Component. ComponentName:{ComponentName}. Cost:{ Cost}. Id: { Id}", model.ComponentName, model.Cost, model.Id); + var element = _componentStorage.GetElement(new ComponentSearchModel{ComponentName = model.ComponentName}); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Компонент с таким названием уже есть"); + } + } + } +} \ No newline at end of file diff --git a/Confectionery/ConfectioneryBusinessLogic/ConfectioneryBusinessLogic.csproj b/Confectionery/ConfectioneryBusinessLogic/ConfectioneryBusinessLogic.csproj new file mode 100644 index 0000000..7191769 --- /dev/null +++ b/Confectionery/ConfectioneryBusinessLogic/ConfectioneryBusinessLogic.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/Confectionery/ConfectioneryBusinessLogic/OrderLogic.cs b/Confectionery/ConfectioneryBusinessLogic/OrderLogic.cs new file mode 100644 index 0000000..7780cce --- /dev/null +++ b/Confectionery/ConfectioneryBusinessLogic/OrderLogic.cs @@ -0,0 +1,125 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Enums; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryBusinessLogic +{ + public class OrderLogic : IOrderLogic + { + private readonly ILogger _logger; + private readonly IOrderStorage _orderStorage; + public OrderLogic(ILogger logger, IOrderStorage orderStorage) + { + _logger = logger; + _orderStorage = orderStorage; + } + 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; + } + public bool CreateOrder(OrderBindingModel model) + { + CheckModel(model); + if (model.Status != OrderStatus.Неизвестен) + return false; + model.Status = OrderStatus.Принят; + if (_orderStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool TakeOrderInWork(OrderBindingModel model) + { + return ChangeStatus(model, OrderStatus.Выполняется); + } + + public bool FinishOrder(OrderBindingModel model) + { + return ChangeStatus(model, OrderStatus.Готов); + } + + public bool DeliveryOrder(OrderBindingModel model) + { + return ChangeStatus(model, OrderStatus.Выдан); + } + + private void CheckModel(OrderBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (model.Count <= 0) + { + throw new ArgumentException("Колличество кондитерских изделий в заказе не может быть меньше 1", nameof(model.Count)); + } + if (model.Sum <= 0) + { + throw new ArgumentException("Стоимость заказа на может быть меньше 1", nameof(model.Sum)); + } + if (model.DateImplement.HasValue && model.DateImplement < model.DateCreate) + { + throw new ArithmeticException($"Дата выдачи заказа {model.DateImplement} не может быть раньше даты его создания {model.DateCreate}"); + } + _logger.LogInformation("Sushi. SushiId:{SushiId}.Count:{Count}.Sum:{Sum}Id:{Id}", + model.PastryId, model.Count, model.Sum, model.Id); + } + + private bool ChangeStatus(OrderBindingModel model, OrderStatus requiredStatus) + { + CheckModel(model, false); + var element = _orderStorage.GetElement(new OrderSearchModel() + { + Id = model.Id + }); + if (element == null) + { + throw new ArgumentNullException(nameof(element)); + } + model.DateCreate = element.DateCreate; + model.PastryId = element.PastryId; + model.DateImplement = element.DateImplement; + model.Status = element.Status; + model.Count = element.Count; + model.Sum = element.Sum; + if (requiredStatus - model.Status == 1) + { + model.Status = requiredStatus; + if (model.Status == OrderStatus.Выдан) + model.DateImplement = DateTime.Now; + if (_orderStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + _logger.LogWarning("Changing status operation faled: Current-{Status}:required-{requiredStatus}.", model.Status, requiredStatus); + throw new ArgumentException($"Невозможно присвоить статус {requiredStatus} заказу с текущим статусом {model.Status}"); + } + } +} diff --git a/Confectionery/ConfectioneryBusinessLogic/PastryLogic.cs b/Confectionery/ConfectioneryBusinessLogic/PastryLogic.cs new file mode 100644 index 0000000..79c4b81 --- /dev/null +++ b/Confectionery/ConfectioneryBusinessLogic/PastryLogic.cs @@ -0,0 +1,113 @@ +using Microsoft.Extensions.Logging; +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryBusinessLogic +{ + internal class PastryLogic : IPastryLogic + { + private readonly ILogger _logger; + private readonly IPastryStorage _PastryStorage; + public PastryLogic(ILogger logger, IPastryStorage PastryStorage) + { + _logger = logger; + _PastryStorage = PastryStorage; + } + public List? ReadList(PastrySearchModel? model) + { + _logger.LogInformation("ReadList. PastryName:{PastryName}.Id:{ Id}", model?.PastryName, model?.Id); + var list = model == null ? _PastryStorage.GetFullList() : _PastryStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + public PastryViewModel? ReadElement(PastrySearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. PastryName:{PastryName}.Id:{ Id}", model.PastryName, model.Id); + var element = _PastryStorage.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(PastryBindingModel model) + { + CheckModel(model); + if (_PastryStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + public bool Update(PastryBindingModel model) + { + CheckModel(model); + if (_PastryStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + public bool Delete(PastryBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_PastryStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + private void CheckModel(PastryBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.PastryName)) + { + throw new ArgumentNullException("Нет названия кондитерского изделия", nameof(model.PastryName)); + } + if (model.Price <= 0) + { + throw new ArgumentNullException("Цена кондитерского изделия должна быть больше 0", nameof(model.Price)); + } + if (model.PastryComponents == null || model.PastryComponents.Count == 0) + { + throw new ArgumentNullException("Перечень ингредиентов не может быть пустым", nameof(model.PastryComponents)); + } + _logger.LogInformation("Pastry. PastryName:{PastryName}.Price:{Price}.Id: { Id}", model.PastryName, model.Price, model.Id); + var element = _PastryStorage.GetElement(new PastrySearchModel{PastryName = model.PastryName}); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Кондитерское изделие с таким названием уже есть"); + } + } + } +} diff --git a/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj b/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj index b0b970c..b6ffff9 100644 --- a/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj +++ b/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj @@ -6,6 +6,10 @@ enable + + + + diff --git a/Confectionery/ConfectioneryContracts/StoragesContracts/IPastryStorage.cs b/Confectionery/ConfectioneryContracts/StoragesContracts/IPastryStorage.cs index f08be11..50d7584 100644 --- a/Confectionery/ConfectioneryContracts/StoragesContracts/IPastryStorage.cs +++ b/Confectionery/ConfectioneryContracts/StoragesContracts/IPastryStorage.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace ConfectioneryContracts.StoragesContracts { - internal interface IPastryStorage + public interface IPastryStorage { List GetFullList(); List GetFilteredList(PastrySearchModel model); diff --git a/Confectionery/ConfectioneryDataModels/ConfectioneryDataModels.csproj b/Confectionery/ConfectioneryDataModels/ConfectioneryDataModels.csproj index 132c02c..28e9bd0 100644 --- a/Confectionery/ConfectioneryDataModels/ConfectioneryDataModels.csproj +++ b/Confectionery/ConfectioneryDataModels/ConfectioneryDataModels.csproj @@ -6,4 +6,8 @@ enable + + + +