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; } } }