diff --git a/BeautyStudio/BeautyStudio.sln b/BeautyStudio/BeautyStudio.sln
index fe123b6..13d9e8e 100644
--- a/BeautyStudio/BeautyStudio.sln
+++ b/BeautyStudio/BeautyStudio.sln
@@ -3,11 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34723.18
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeautyStudioView", "BeautyStudioView\BeautyStudioView.csproj", "{DCC3ADED-6BBE-4B54-AADB-59237361F601}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BeautyStudioView", "BeautyStudioView\BeautyStudioView.csproj", "{DCC3ADED-6BBE-4B54-AADB-59237361F601}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeautyStudioDataModels", "BeautyStudioDataModels\BeautyStudioDataModels.csproj", "{7C1604C6-4223-47A7-B651-687BBF19704B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BeautyStudioDataModels", "BeautyStudioDataModels\BeautyStudioDataModels.csproj", "{7C1604C6-4223-47A7-B651-687BBF19704B}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeautyStudioContracts", "BeautyStudioContracts\BeautyStudioContracts.csproj", "{BD48E4B8-A4A1-4A80-97AE-8599BDD41892}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BeautyStudioContracts", "BeautyStudioContracts\BeautyStudioContracts.csproj", "{BD48E4B8-A4A1-4A80-97AE-8599BDD41892}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeautyStudioBusinessLogic", "BeautyStudioBusinessLogic\BeautyStudioBusinessLogic.csproj", "{25B40F20-807F-4A09-80E5-4A94EE480FB6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -27,6 +29,10 @@ Global
{BD48E4B8-A4A1-4A80-97AE-8599BDD41892}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD48E4B8-A4A1-4A80-97AE-8599BDD41892}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD48E4B8-A4A1-4A80-97AE-8599BDD41892}.Release|Any CPU.Build.0 = Release|Any CPU
+ {25B40F20-807F-4A09-80E5-4A94EE480FB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {25B40F20-807F-4A09-80E5-4A94EE480FB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {25B40F20-807F-4A09-80E5-4A94EE480FB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {25B40F20-807F-4A09-80E5-4A94EE480FB6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/BeautyStudio/BeautyStudioBusinessLogic/BeautyStudioBusinessLogic.csproj b/BeautyStudio/BeautyStudioBusinessLogic/BeautyStudioBusinessLogic.csproj
new file mode 100644
index 0000000..80e0a5b
--- /dev/null
+++ b/BeautyStudio/BeautyStudioBusinessLogic/BeautyStudioBusinessLogic.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/ClientLogic.cs b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/ClientLogic.cs
new file mode 100644
index 0000000..97d4ef0
--- /dev/null
+++ b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/ClientLogic.cs
@@ -0,0 +1,155 @@
+using BeautyStudioContracts.BindingModels;
+using BeautyStudioContracts.BusinessLogicContracts;
+using BeautyStudioContracts.SearchModels;
+using BeautyStudioContracts.StoragesContracts;
+using BeautyStudioContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+
+namespace BeautyStudioBusinessLogic.BusinessLogic
+{
+ public class ClientLogic : IClientLogic
+ {
+ private readonly int _passwordMaxLength = 50;
+ private readonly int _passwordMinLength = 10;
+
+ private readonly ILogger _logger;
+ private readonly IClientStorage _clientStorage;
+ public ClientLogic(ILogger logger, IClientStorage clientStorage)
+ {
+ _logger = logger;
+ _clientStorage = clientStorage;
+ }
+ public bool Create(ClientBindingModel model)
+ {
+ CheckModel(model);
+
+ if (_clientStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool Delete(ClientBindingModel model)
+ {
+ CheckModel(model, false);
+
+ _logger.LogInformation("Delete. Id: {Id}", model.Id);
+
+ if (_clientStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public ClientViewModel? ReadElement(ClientSearchModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+
+ _logger.LogInformation("ReadElement. ClientLogin: {ClientLogin}. ClientFIO: {ClientFIO} ClientEmail: {ClientEmail} Id: {Id}",
+ model.ClientFIO, model.ClientLogin, model.ClientEmail, model.Id);
+
+ var element = _clientStorage.GetElement(model);
+
+ if (element == null)
+ {
+ _logger.LogWarning("ReadElement element not found");
+ return null;
+ }
+
+ _logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
+
+ return element;
+ }
+
+ public List? ReadList(ClientSearchModel? model)
+ {
+ _logger.LogInformation("ReadList. ClientLogin: {ClientLogin}. ClientFIO: {ClientFIO} ClientEmail: {ClientEmail} Id: {Id}",
+ model?.ClientFIO, model?.ClientLogin, model?.ClientEmail, model?.Id);
+
+ var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model);
+
+ if (list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+
+ _logger.LogInformation("ReadList. Count: {Count}", list.Count);
+
+ return list;
+ }
+
+ public bool Update(ClientBindingModel model)
+ {
+ CheckModel(model);
+
+ if (_clientStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+ return true;
+ }
+
+ private void CheckModel(ClientBindingModel model, bool withParams = true)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+
+ if (!withParams)
+ {
+ return;
+ }
+ if (string.IsNullOrEmpty(model.ClientFIO))
+ {
+ throw new ArgumentNullException("Нет ФИО клиента", nameof(model.ClientFIO));
+ }
+ if (string.IsNullOrEmpty(model.ClientLogin))
+ {
+ throw new ArgumentNullException("Нет логина клиента", nameof(model.ClientLogin));
+ }
+ if (string.IsNullOrEmpty(model.ClientEmail))
+ {
+ throw new ArgumentNullException("Нет почты клиента", nameof(model.ClientEmail));
+ }
+ if (string.IsNullOrEmpty(model.ClientPassword))
+ {
+ throw new ArgumentNullException("Нет пароля", nameof(model.ClientPassword));
+ }
+ if (model.ClientPassword.Length < _passwordMinLength)
+ {
+ throw new ArgumentNullException("Пароль слишком короткий", nameof(model.ClientPassword));
+ }
+ if (model.ClientPassword.Length > _passwordMaxLength)
+ {
+ throw new ArgumentNullException("Пароль слишком длинный", nameof(model.ClientPassword));
+ }
+
+ _logger.LogInformation("Client. ClientFIO: {ClientFIO}. ClientLogin: {ClientLogin} ClientEmail: {ClientEmail} Id: {Id}",
+ model.ClientFIO, model.ClientLogin, model.ClientEmail, model.Id);
+
+ var element = _clientStorage.GetElement(new ClientSearchModel
+ {
+ ClientEmail = model.ClientEmail
+ });
+
+ if (element != null && element.Id != model.Id)
+ {
+ throw new InvalidOperationException("Клиент с такой почтой уже есть");
+ }
+ }
+ }
+}
diff --git a/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/CosmeticLogic.cs b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/CosmeticLogic.cs
new file mode 100644
index 0000000..bfdeba7
--- /dev/null
+++ b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/CosmeticLogic.cs
@@ -0,0 +1,116 @@
+using BeautyStudioContracts.BindingModels;
+using BeautyStudioContracts.BusinessLogicContracts;
+using BeautyStudioContracts.SearchModels;
+using BeautyStudioContracts.StoragesContracts;
+using BeautyStudioContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BeautyStudioBusinessLogic.BusinessLogic
+{
+ public class CosmeticLogic : ICosmeticLogic
+ {
+ private readonly ILogger _logger;
+ private readonly ICosmeticStorage _cosmeticStorage;
+ public CosmeticLogic(ILogger logger, ICosmeticStorage cosmeticStorage)
+ {
+ _logger = logger;
+ _cosmeticStorage = cosmeticStorage;
+ }
+ public List? ReadList(CosmeticSearchModel? model)
+ {
+ _logger.LogInformation("ReadList. CosmeticName: {CosmeticName}. Id: {Id}",
+ model?.CosmeticName, model?.Id);
+ var list = model == null ? _cosmeticStorage.GetFullList() :
+ _cosmeticStorage.GetFilteredList(model);
+ if (list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+ _logger.LogInformation("ReadList. Count: {Count}", list.Count);
+ return list;
+ }
+ public CosmeticViewModel? ReadElement(CosmeticSearchModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ _logger.LogInformation("ReadElement. CosmeticName: {CosmeticName}. Id: {Id}",
+ model.CosmeticName, model.Id);
+ var element = _cosmeticStorage.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(CosmeticBindingModel model)
+ {
+ CheckModel(model);
+ if (_cosmeticStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Update(CosmeticBindingModel model)
+ {
+ CheckModel(model);
+ if (_cosmeticStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Delete(CosmeticBindingModel model)
+ {
+ CheckModel(model, false);
+ _logger.LogInformation("Delete. Id: {Id}", model.Id);
+ if (_cosmeticStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+ return false;
+ }
+ return true;
+ }
+ private void CheckModel(CosmeticBindingModel model, bool withParams = true)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ if (!withParams)
+ {
+ return;
+ }
+ if (string.IsNullOrEmpty(model.CosmeticName))
+ {
+ throw new ArgumentNullException("Нет названия косметики", nameof(model.CosmeticName));
+ }
+ if (model.CosmeticPrice <= 0)
+ {
+ throw new ArgumentNullException("Цена косметики должна быть больше 0", nameof(model.CosmeticPrice));
+ }
+ _logger.LogInformation("Cosmetic. CosmeticName: {CosmeticName}. CosmeticPrice: {CosmeticPrice}. Id: {Id}",
+ model.CosmeticName, model.CosmeticPrice, model.Id);
+ var element = _cosmeticStorage.GetElement(new CosmeticSearchModel
+ {
+ CosmeticName = model.CosmeticName
+ });
+ if (element != null && element.Id != model.Id)
+ {
+ throw new InvalidOperationException("Косметика с таким названием уже есть");
+ }
+ }
+ }
+}
diff --git a/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/LaborCostsLogic.cs b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/LaborCostsLogic.cs
new file mode 100644
index 0000000..561e416
--- /dev/null
+++ b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/LaborCostsLogic.cs
@@ -0,0 +1,106 @@
+using BeautyStudioContracts.BindingModels;
+using BeautyStudioContracts.BusinessLogicContracts;
+using BeautyStudioContracts.SearchModels;
+using BeautyStudioContracts.StoragesContracts;
+using BeautyStudioContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BeautyStudioBusinessLogic.BusinessLogics
+{
+ public class LaborCostLogic : ILaborCostLogic
+ {
+ private readonly ILogger _logger;
+ private readonly ILaborCostStorage _laborCostsStorage;
+ public LaborCostLogic(ILogger logger, ILaborCostStorage laborCostsStorage)
+ {
+ _logger = logger;
+ _laborCostsStorage = laborCostsStorage;
+ }
+
+ public List? ReadList(LaborCostSearchModel? model)
+ {
+ _logger.LogInformation("ReadList. Id: {Id}",
+ model?.Id);
+ var list = model == null ? _laborCostsStorage.GetFullList() :
+ _laborCostsStorage.GetFilteredList(model);
+ if (list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+ _logger.LogInformation("ReadList. Count: {Count}", list.Count);
+ return list;
+ }
+ public LaborCostViewModel? ReadElement(LaborCostSearchModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ _logger.LogInformation("ReadElement. Id: {Id}",
+ model.Id);
+ var element = _laborCostsStorage.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(LaborCostBindingModel model)
+ {
+ CheckModel(model);
+ if (_laborCostsStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Update(LaborCostBindingModel model)
+ {
+ CheckModel(model);
+ if (_laborCostsStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Delete(LaborCostBindingModel model)
+ {
+ CheckModel(model, false);
+ _logger.LogInformation("Delete. Id: {Id}", model.Id);
+ if (_laborCostsStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+ return false;
+ }
+ return true;
+ }
+ private void CheckModel(LaborCostBindingModel model, bool withParams = true)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ if (!withParams)
+ {
+ return;
+ }
+ if (model.TimeSpent <= 0)
+ {
+ throw new ArgumentNullException("Количество часов должно быть больше 0", nameof(model.TimeSpent));
+ }
+
+ _logger.LogInformation("LaborCost. TimeSpent: {TimeSpent}. Difficulty: {Difficulty}. Id: {Id}",
+ model.TimeSpent, model.Id);
+ }
+ }
+}
diff --git a/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/OrderLogic.cs b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/OrderLogic.cs
new file mode 100644
index 0000000..6f78571
--- /dev/null
+++ b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/OrderLogic.cs
@@ -0,0 +1,102 @@
+using BeautyStudioContracts.BindingModels;
+using BeautyStudioContracts.BusinessLogicContracts;
+using BeautyStudioContracts.SearchModels;
+using BeautyStudioContracts.StoragesContracts;
+using BeautyStudioContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BeautyStudioBusinessLogic.BusinessLogics
+{
+ 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("Order. 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 OrderViewModel? ReadElement(OrderSearchModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ _logger.LogInformation("ReadElement. DateCreate: {DateCreate}. Id: {Id}",
+ model.DateCreate, model.Id);
+ var element = _orderStorage.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(OrderBindingModel model)
+ {
+ CheckModel(model);
+ if (_orderStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Update(OrderBindingModel model)
+ {
+ CheckModel(model);
+ if (_orderStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Delete(OrderBindingModel model)
+ {
+ CheckModel(model, false);
+ _logger.LogInformation("Delete. Id: {Id}", model.Id);
+ if (_orderStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+ return false;
+ }
+ return true;
+ }
+ private void CheckModel(OrderBindingModel model, bool withParams = true)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ if (!withParams)
+ {
+ return;
+ }
+ if (model.OrderAmount <= 0)
+ {
+ throw new ArgumentNullException("Cумма заказа должна быть больше 0",
+ nameof(model.OrderAmount));
+ }
+ }
+ }
+}
diff --git a/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/ProcedureLogic.cs b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/ProcedureLogic.cs
new file mode 100644
index 0000000..84a0e39
--- /dev/null
+++ b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/ProcedureLogic.cs
@@ -0,0 +1,120 @@
+using BeautyStudioContracts.BindingModels;
+using BeautyStudioContracts.BusinessLogicContracts;
+using BeautyStudioContracts.SearchModels;
+using BeautyStudioContracts.StoragesContracts;
+using BeautyStudioContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BeautyStudioBusinessLogic.BusinessLogics
+{
+ public class ProcedureLogic : IProcedureLogic
+ {
+ private readonly ILogger _logger;
+ private readonly IProcedureStorage _procedureStorage;
+ public ProcedureLogic(ILogger logger, IProcedureStorage procedureStorage)
+ {
+ _logger = logger;
+ _procedureStorage = procedureStorage;
+ }
+
+
+ public List? ReadList(ProcedureSearchModel? model)
+ {
+ _logger.LogInformation("ReadList. ProcedureName: {ProcedureName}. Id: {Id}",
+ model?.ProcedureName, model?.Id);
+ var list = model == null ? _procedureStorage.GetFullList() :
+ _procedureStorage.GetFilteredList(model);
+ if (list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+ _logger.LogInformation("ReadList. Count: {Count}", list.Count);
+ return list;
+ }
+ public ProcedureViewModel? ReadElement(ProcedureSearchModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ _logger.LogInformation("ReadElement. ProcedureName: {ProcedureName}. Id: {Id}",
+ model.ProcedureName, model.Id);
+ var element = _procedureStorage.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(ProcedureBindingModel model)
+ {
+ CheckModel(model);
+ if (_procedureStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Update(ProcedureBindingModel model)
+ {
+ CheckModel(model);
+ if (_procedureStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Delete(ProcedureBindingModel model)
+ {
+ CheckModel(model, false);
+ _logger.LogInformation("Delete. Id: {Id}", model.Id);
+ if (_procedureStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+ return false;
+ }
+ return true;
+ }
+ private void CheckModel(ProcedureBindingModel model, bool withParams = true)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ if (!withParams)
+ {
+ return;
+ }
+ if (string.IsNullOrEmpty(model.ProcedureName))
+ {
+ throw new ArgumentNullException("Нет названия процедуры", nameof(model.ProcedureName));
+ }
+
+ if (model.ProcedurePrice <= 0)
+ {
+ throw new ArgumentNullException("Цена процедуры должна быть больше 0",
+ nameof(model.ProcedurePrice));
+ }
+ _logger.LogInformation("Procedure. ProcedureName: {ProcedureName}. Cost: {Cost}. Id: {Id}",
+ model.ProcedureName, model.ProcedurePrice, model.Id);
+ var element = _procedureStorage.GetElement(new ProcedureSearchModel
+ {
+ ProcedureName = model.ProcedureName
+ });
+ if (element != null && element.Id != model.Id)
+ {
+ throw new InvalidOperationException("Процедура с таким названием уже есть");
+ }
+ }
+ }
+}
diff --git a/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/ServiceLogic.cs b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/ServiceLogic.cs
new file mode 100644
index 0000000..77bd596
--- /dev/null
+++ b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/ServiceLogic.cs
@@ -0,0 +1,119 @@
+using BeautyStudioContracts.BindingModels;
+using BeautyStudioContracts.BusinessLogicContracts;
+using BeautyStudioContracts.SearchModels;
+using BeautyStudioContracts.StoragesContracts;
+using BeautyStudioContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BeautyStudioBusinessLogic.BusinessLogics
+{
+ public class ServiceLogic : IServiceLogic
+ {
+ private readonly ILogger _logger;
+ private readonly IServiceStorage _serviceStorage;
+ public ServiceLogic(ILogger logger, IServiceStorage serviceStorage)
+ {
+ _logger = logger;
+ _serviceStorage = serviceStorage;
+ }
+
+ public List? ReadList(ServiceSearchModel? model)
+ {
+ _logger.LogInformation("ReadList. ServiceName: {ServiceName}. Id: {Id}",
+ model?.ServiceName, model?.Id);
+ var list = model == null ? _serviceStorage.GetFullList() :
+ _serviceStorage.GetFilteredList(model);
+ if (list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+ _logger.LogInformation("ReadList. Count: {Count}", list.Count);
+ return list;
+ }
+ public ServiceViewModel? ReadElement(ServiceSearchModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ _logger.LogInformation("ReadElement. ServiceName: {ServiceName}. Id: {Id}",
+ model.ServiceName, model.Id);
+ var element = _serviceStorage.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(ServiceBindingModel model)
+ {
+ CheckModel(model);
+ if (_serviceStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Update(ServiceBindingModel model)
+ {
+ CheckModel(model);
+ if (_serviceStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Delete(ServiceBindingModel model)
+ {
+ CheckModel(model, false);
+ _logger.LogInformation("Delete. Id: {Id}", model.Id);
+ if (_serviceStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+ return false;
+ }
+ return true;
+ }
+ private void CheckModel(ServiceBindingModel model, bool withParams = true)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ if (!withParams)
+ {
+ return;
+ }
+ if (string.IsNullOrEmpty(model.ServiceName))
+ {
+ throw new ArgumentNullException("Нет названия услуги", nameof(model.ServiceName));
+ }
+
+ if (model.ServicePrice <= 0)
+ {
+ throw new ArgumentNullException("Цена услуги должна быть больше 0",
+ nameof(model.ServicePrice));
+ }
+ _logger.LogInformation("Service. ServiceName: {ServiceName}. Cost: {Cost}. Id: {Id}",
+ model.ServiceName, model.ServicePrice, model.Id);
+ var element = _serviceStorage.GetElement(new ServiceSearchModel
+ {
+ ServiceName = model.ServiceName
+ });
+ if (element != null && element.Id != model.Id)
+ {
+ throw new InvalidOperationException("Услуга с таким названием уже есть");
+ }
+ }
+ }
+}
diff --git a/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/StaffLogic.cs b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/StaffLogic.cs
new file mode 100644
index 0000000..19cb982
--- /dev/null
+++ b/BeautyStudio/BeautyStudioBusinessLogic/BusinessLogic/StaffLogic.cs
@@ -0,0 +1,159 @@
+using BeautyStudioContracts.BindingModels;
+using BeautyStudioContracts.BusinessLogicContracts;
+using BeautyStudioContracts.SearchModels;
+using BeautyStudioContracts.StoragesContracts;
+using BeautyStudioContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+
+namespace BeautyStudioBusinessLogic.BusinessLogics
+{
+ public class StaffLogic : IStaffLogic
+ {
+ private readonly int _passwordMaxLength = 25;
+ private readonly int _passwordMinLength = 6;
+
+ private readonly ILogger _logger;
+ private readonly IStaffStorage _staffMemberStorage;
+ public StaffLogic(ILogger logger, IStaffStorage staffMemberStorage)
+ {
+ _logger = logger;
+ _staffMemberStorage = staffMemberStorage;
+ }
+ public bool Create(StaffBindingModel model)
+ {
+ CheckModel(model);
+
+ if (_staffMemberStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool Delete(StaffBindingModel model)
+ {
+ CheckModel(model, false);
+
+ _logger.LogInformation("Delete. Id: {Id}", model.Id);
+
+ if (_staffMemberStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public StaffViewModel? ReadElement(StaffSearchModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+
+ _logger.LogInformation("ReadElement. StaffLogin: {StaffLogin}. StaffEmail: {StaffEmail} Id: {Id}",
+ model.StaffLogin, model.StaffEmail, model.Id);
+
+ var element = _staffMemberStorage.GetElement(model);
+
+ if (element == null)
+ {
+ _logger.LogWarning("ReadElement element not found");
+ return null;
+ }
+
+ _logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
+
+ return element;
+ }
+
+ public List? ReadList(StaffSearchModel? model)
+ {
+ _logger.LogInformation("ReadElement. StaffLogin: {StaffLogin}. StaffEmail: {StaffEmail} Id: {Id}",
+ model?.StaffLogin, model?.StaffEmail, model?.Id);
+
+ var list = model == null ? _staffMemberStorage.GetFullList() : _staffMemberStorage.GetFilteredList(model);
+
+ if (list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+
+ _logger.LogInformation("ReadList. Count: {Count}", list.Count);
+
+ return list;
+ }
+
+ public bool Update(StaffBindingModel model)
+ {
+ CheckModel(model);
+
+ if (_staffMemberStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+ return true;
+ }
+ private void CheckModel(StaffBindingModel model, bool withParams = true)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+
+ if (!withParams)
+ {
+ return;
+ }
+ if (string.IsNullOrEmpty(model.StaffFIO))
+ {
+ throw new ArgumentNullException("Нет имени сотрудника", nameof(model.StaffLogin));
+ }
+ if (string.IsNullOrEmpty(model.StaffLogin))
+ {
+ throw new ArgumentNullException("Нет логина сотрудника", nameof(model.StaffLogin));
+ }
+ if (string.IsNullOrEmpty(model.StaffEmail))
+ {
+ throw new ArgumentNullException("Нет почты сотрудника", nameof(model.StaffEmail));
+ }
+ if (string.IsNullOrEmpty(model.StaffPassword))
+ {
+ throw new ArgumentNullException("Нет пароля сотрудника", nameof(model.StaffPassword));
+ }
+ if (string.IsNullOrEmpty(model.StaffPhone))
+ {
+ throw new ArgumentNullException("Нет телефона сотрудника", nameof(model.StaffEmail));
+ }
+
+ if (model.StaffPassword.Length < _passwordMinLength)
+ {
+ throw new ArgumentNullException("Пароль слишком короткий", nameof(model.StaffPassword));
+ }
+
+ if (model.StaffPassword.Length > _passwordMaxLength)
+ {
+ throw new ArgumentNullException("Пароль слишком длинный", nameof(model.StaffPassword));
+ }
+ _logger.LogInformation("ReadElement. StaffLogin: {StaffLogin}. StaffEmail: {StaffEmail} Id: {Id}",
+ model.StaffLogin, model.StaffEmail, model.Id);
+
+ var element = _staffMemberStorage.GetElement(new StaffSearchModel
+ {
+ StaffEmail = model.StaffEmail
+ });
+
+ if (element != null && element.Id != model.Id)
+ {
+ throw new InvalidOperationException("Сотрудник с такой почтой уже есть");
+ }
+ }
+ }
+}