diff --git a/BeautySalon/BeautySalon.sln b/BeautySalon/BeautySalon.sln
index d55dc1e..fa561a8 100644
--- a/BeautySalon/BeautySalon.sln
+++ b/BeautySalon/BeautySalon.sln
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeautySalonDataModels", "..
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeautySalonContracts", "..\BeauySalonContracts\BeautySalonContracts.csproj", "{8CBBB8D6-5615-417B-82C5-B069EA84AB3C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeautySalonBusinessLogic", "..\BeautySalonBusinessLogic\BeautySalonBusinessLogic.csproj", "{EC867077-D21F-4D12-9BD5-16244A3D119C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,10 @@ Global
{8CBBB8D6-5615-417B-82C5-B069EA84AB3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CBBB8D6-5615-417B-82C5-B069EA84AB3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CBBB8D6-5615-417B-82C5-B069EA84AB3C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EC867077-D21F-4D12-9BD5-16244A3D119C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC867077-D21F-4D12-9BD5-16244A3D119C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC867077-D21F-4D12-9BD5-16244A3D119C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC867077-D21F-4D12-9BD5-16244A3D119C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/BeautySalonBusinessLogic/BeautySalonBusinessLogic.csproj b/BeautySalonBusinessLogic/BeautySalonBusinessLogic.csproj
new file mode 100644
index 0000000..6a2edb8
--- /dev/null
+++ b/BeautySalonBusinessLogic/BeautySalonBusinessLogic.csproj
@@ -0,0 +1,17 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BeautySalonBusinessLogic/BusinessLogics/ClientLogic.cs b/BeautySalonBusinessLogic/BusinessLogics/ClientLogic.cs
new file mode 100644
index 0000000..1a74081
--- /dev/null
+++ b/BeautySalonBusinessLogic/BusinessLogics/ClientLogic.cs
@@ -0,0 +1,111 @@
+using BeautySalonContracts.BindingModels;
+using BeautySalonContracts.BusinessLogicsContracts;
+using BeautySalonContracts.SearchModels;
+using BeautySalonContracts.StoragesContracts;
+using BeautySalonContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+
+namespace BeautySalonBusinessLogic.BusinessLogics
+{
+ public class ClientLogic : IClientLogic
+ {
+ 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. PhoneNumber: {PhoneNumber} Id:{ Id}", model.PhoneNumber, 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. PhoneNumber: {PhoneNumber}. Id:{ Id}", model?.PhoneNumber, 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.PhoneNumber))
+ {
+ throw new ArgumentNullException("Нет номера телефона клиента", nameof(model.PhoneNumber));
+ }
+ _logger.LogInformation("Client. ClientFIO:{ClientFIO}. PhoneNumber:{ PhoneNumber}. Id: { Id}", model.ClientFIO, model.PhoneNumber, model.Id);
+ var element = _clientStorage.GetElement(new ClientSearchModel { PhoneNumber = model.PhoneNumber });
+ if (element != null && element.Id != model.Id)
+ {
+ throw new InvalidOperationException("Клиент с таким номером уже есть");
+ }
+ }
+ }
+}
diff --git a/BeautySalonBusinessLogic/BusinessLogics/MasterLogic.cs b/BeautySalonBusinessLogic/BusinessLogics/MasterLogic.cs
new file mode 100644
index 0000000..4396541
--- /dev/null
+++ b/BeautySalonBusinessLogic/BusinessLogics/MasterLogic.cs
@@ -0,0 +1,107 @@
+using BeautySalonContracts.BindingModels;
+using BeautySalonContracts.BusinessLogicsContracts;
+using BeautySalonContracts.SearchModels;
+using BeautySalonContracts.StoragesContracts;
+using BeautySalonContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+
+namespace BeautySalonBusinessLogic.BusinessLogics
+{
+ public class MasterLogic : IMasterLogic
+ {
+ private readonly ILogger _logger;
+ private readonly IMasterStorage _masterStorage;
+ public MasterLogic(ILogger logger, IMasterStorage masterStorage)
+ {
+ _logger = logger;
+ _masterStorage = masterStorage;
+ }
+ public List? ReadList(MasterSearchModel? model)
+ {
+ _logger.LogInformation("ReadList. MasterFIO:{MasterFIO}. Id:{ Id}", model?.MasterFIO, model?.Id);
+ var list = model == null ? _masterStorage.GetFullList() : _masterStorage.GetFilteredList(model);
+ if (list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+ _logger.LogInformation("ReadList. Count:{Count}", list.Count);
+ return list;
+ }
+ public MasterViewModel? ReadElement(MasterSearchModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ _logger.LogInformation("ReadElement. MasterFIO:{MasterFIO}. Id:{ Id}", model.MasterFIO, model.Id);
+ var element = _masterStorage.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(MasterBindingModel model)
+ {
+ CheckModel(model);
+ if (_masterStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Update(MasterBindingModel model)
+ {
+ CheckModel(model);
+ if (_masterStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Delete(MasterBindingModel model)
+ {
+ CheckModel(model, false);
+ _logger.LogInformation("Delete. Id:{Id}", model.Id);
+ if (_masterStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+ return false;
+ }
+ return true;
+ }
+ private void CheckModel(MasterBindingModel model, bool withParams = true)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ if (!withParams)
+ {
+ return;
+ }
+ if (string.IsNullOrEmpty(model.MasterFIO))
+ {
+ throw new ArgumentNullException("Нет ФИО мастера", nameof(model.MasterFIO));
+ }
+ if (string.IsNullOrEmpty(model.Specialization))
+ {
+ throw new ArgumentNullException("Нет специализации мастера", nameof(model.MasterFIO));
+ }
+ _logger.LogInformation("Master. MasterFIO:{MasterFIO}. Specialization:{ Specialization}. Id: { Id} ", model.MasterFIO, model.Specialization, model.Id);
+ var element = _masterStorage.GetElement(new MasterSearchModel
+ {
+ MasterFIO = model.MasterFIO
+ });
+ if (element != null && element.Id != model.Id)
+ {
+ throw new InvalidOperationException("Мастер с таким ФИО уже есть");
+ }
+ }
+ }
+}
diff --git a/BeautySalonBusinessLogic/BusinessLogics/ServiceLogic.cs b/BeautySalonBusinessLogic/BusinessLogics/ServiceLogic.cs
new file mode 100644
index 0000000..f6b2469
--- /dev/null
+++ b/BeautySalonBusinessLogic/BusinessLogics/ServiceLogic.cs
@@ -0,0 +1,107 @@
+using BeautySalonContracts.BindingModels;
+using BeautySalonContracts.BusinessLogicsContracts;
+using BeautySalonContracts.SearchModels;
+using BeautySalonContracts.StoragesContracts;
+using BeautySalonContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+
+namespace BeautySalonBusinessLogic.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.Cost <= 0)
+ {
+ throw new ArgumentNullException("Цена услуги должна быть больше 0", nameof(model.Cost));
+ }
+ _logger.LogInformation("Service. ServiceName:{ServiceName}. Cost:{ Cost}. Id: { Id} ", model.ServiceName, model.Cost, model.Id);
+ var element = _serviceStorage.GetElement(new ServiceSearchModel
+ {
+ ServiceName = model.ServiceName
+ });
+ if (element != null && element.Id != model.Id)
+ {
+ throw new InvalidOperationException("Услуга с таким названием уже есть");
+ }
+ }
+ }
+}
diff --git a/BeautySalonBusinessLogic/BusinessLogics/VisitLogic.cs b/BeautySalonBusinessLogic/BusinessLogics/VisitLogic.cs
new file mode 100644
index 0000000..0f89116
--- /dev/null
+++ b/BeautySalonBusinessLogic/BusinessLogics/VisitLogic.cs
@@ -0,0 +1,95 @@
+using BeautySalonContracts.BindingModels;
+using BeautySalonContracts.BusinessLogicsContracts;
+using BeautySalonContracts.SearchModels;
+using BeautySalonContracts.StoragesContracts;
+using BeautySalonContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+
+namespace BeautySalonBusinessLogic.BusinessLogics
+{
+ public class VisitLogic : IVisitLogic
+ {
+ private readonly ILogger _logger;
+ private readonly IVisitStorage _visitStorage;
+ public VisitLogic(ILogger logger, IVisitStorage visitStorage)
+ {
+ _logger = logger;
+ _visitStorage = visitStorage;
+ }
+ public List? ReadList(VisitSearchModel? model)
+ {
+ _logger.LogInformation("ReadList. VisitId:{VisitId}.", model?.Id);
+ var list = model == null ? _visitStorage.GetFullList() : _visitStorage.GetFilteredList(model);
+ if (list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+ _logger.LogInformation("ReadList. Count:{Count}", list.Count);
+ return list;
+ }
+ public VisitViewModel? ReadElement(VisitSearchModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ _logger.LogInformation("ReadElement. Id:{ Id}", model.Id);
+ var element = _visitStorage.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(VisitBindingModel model)
+ {
+ CheckModel(model);
+ if (_visitStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Update(VisitBindingModel model)
+ {
+ CheckModel(model);
+ if (_visitStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+ return true;
+ }
+ public bool Delete(VisitBindingModel model)
+ {
+ CheckModel(model);
+ _logger.LogInformation("Delete. Id:{Id}", model.Id);
+ if (_visitStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+ return false;
+ }
+ return true;
+ }
+ private bool CheckModel(VisitBindingModel model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ if (model.Count <= 0)
+ {
+ throw new ArgumentNullException("Количество услуг должно быть больше 0", nameof(model.Count));
+ }
+ if (model.Sum <= 0)
+ {
+ throw new ArgumentNullException("Суммарная стоимость должна быть больше 0", nameof(model.Sum));
+ }
+ return true;
+ }
+ }
+}
diff --git a/BeautySalonDataModels/Models/IVisitModel.cs b/BeautySalonDataModels/Models/IVisitModel.cs
index 22e53c6..4a3e2db 100644
--- a/BeautySalonDataModels/Models/IVisitModel.cs
+++ b/BeautySalonDataModels/Models/IVisitModel.cs
@@ -6,5 +6,7 @@
int ClientId { get; }
int MasterId { get; }
int ServiceId { get; }
+ double Sum { get; }
+ int Count { get; }
}
}
diff --git a/BeauySalonContracts/BindingModels/VisitBindingModel.cs b/BeauySalonContracts/BindingModels/VisitBindingModel.cs
index 6182015..1020a65 100644
--- a/BeauySalonContracts/BindingModels/VisitBindingModel.cs
+++ b/BeauySalonContracts/BindingModels/VisitBindingModel.cs
@@ -9,5 +9,7 @@ namespace BeautySalonContracts.BindingModels
public int ClientId { get; set; }
public int MasterId { get; set; }
public int ServiceId { get; set; }
+ public double Sum { get; set; }
+ public int Count { get; set; }
}
}
diff --git a/BeauySalonContracts/ViewModels/VisitViewModel.cs b/BeauySalonContracts/ViewModels/VisitViewModel.cs
index ea77b51..cab63b9 100644
--- a/BeauySalonContracts/ViewModels/VisitViewModel.cs
+++ b/BeauySalonContracts/ViewModels/VisitViewModel.cs
@@ -1,13 +1,19 @@
using BeautySalonDataModels.Models;
+using System.ComponentModel;
namespace BeautySalonContracts.ViewModels
{
public class VisitViewModel : IVisitModel
{
public int Id { get; set; }
+ [DisplayName("Дата посещения")]
public DateTime DateOfVisit { get; set; }
public int ClientId { get; set; }
public int MasterId { get; set; }
public int ServiceId { get; set; }
+ [DisplayName("Сумма")]
+ public double Sum { get; set; }
+ [DisplayName("Количество")]
+ public int Count { get; set; }
}
}