From aceba1ae3c49d57bc95ffcb345681ac3f621232e Mon Sep 17 00:00:00 2001 From: Sergey Kozyrev Date: Tue, 2 Apr 2024 20:44:57 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A8=D0=BE=D1=82=D0=BE=20=D1=81=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D0=BD=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogic/ClientLogic.cs | 118 ++++++++++++++++++ .../BindingModels/ClientBindingModel.cs | 12 ++ .../BindingModels/OrderBindingModel.cs | 2 + .../BusinessLogicsContracts/IClientLogic.cs | 15 +++ .../SearchModels/ClientSearchModel.cs | 8 ++ .../SearchModels/OrderSearchModel.cs | 1 + .../StoragesContracts/IClientStorage.cs | 16 +++ .../ViewModels/ClientViewModel.cs | 16 +++ .../ViewModels/OrderViewModel.cs | 3 + .../Models/IClientModel.cs | 9 ++ .../Implements/ClientStorage.cs | 62 +++++++++ .../Models/Client.cs | 54 ++++++++ .../Models/Order.cs | 3 + .../SewingDressesDatabase.cs | 1 + 14 files changed, 320 insertions(+) create mode 100644 SewingDresses/SewingDressesBusinessLogic/BusinessLogic/ClientLogic.cs create mode 100644 SewingDresses/SewingDressesContracts/BindingModels/ClientBindingModel.cs create mode 100644 SewingDresses/SewingDressesContracts/BusinessLogicsContracts/IClientLogic.cs create mode 100644 SewingDresses/SewingDressesContracts/SearchModels/ClientSearchModel.cs create mode 100644 SewingDresses/SewingDressesContracts/StoragesContracts/IClientStorage.cs create mode 100644 SewingDresses/SewingDressesContracts/ViewModels/ClientViewModel.cs create mode 100644 SewingDresses/SewingDressesDataModels/Models/IClientModel.cs create mode 100644 SewingDresses/SewingDressesDatabaseImplement/Implements/ClientStorage.cs create mode 100644 SewingDresses/SewingDressesDatabaseImplement/Models/Client.cs diff --git a/SewingDresses/SewingDressesBusinessLogic/BusinessLogic/ClientLogic.cs b/SewingDresses/SewingDressesBusinessLogic/BusinessLogic/ClientLogic.cs new file mode 100644 index 0000000..a9d7c03 --- /dev/null +++ b/SewingDresses/SewingDressesBusinessLogic/BusinessLogic/ClientLogic.cs @@ -0,0 +1,118 @@ +using Microsoft.Extensions.Logging; +using SewingDressesContracts.BindingModels; +using SewingDressesContracts.BusinessLogicsContracts; +using SewingDressesContracts.SearchModels; +using SewingDressesContracts.StoragesContracts; +using SewingDressesContracts.ViewModels; + +namespace SewingDressesBusinessLogic.BusinessLogic +{ + 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) + { + CheckUser(model); + if (_clientStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + public bool Update(ClientBindingModel model) + { + CheckUser(model); + if (_clientStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + public bool Delete(ClientBindingModel model) + { + CheckUser(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. UserName:{UserName}.Id:{Id}", model.Email, 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. UserName:{UserName}. Id:{Id}", model?.Email, 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 void CheckUser(ClientBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.ClientFIO)) + { + throw new ArgumentNullException("Invalid fullname of user", nameof(model.ClientFIO)); + } + if (string.IsNullOrEmpty(model.Email)) + { + throw new ArgumentNullException("Invalid email of user", nameof(model.Email)); + } + if (string.IsNullOrEmpty(model.Password)) + { + throw new ArgumentNullException("Invalid password of user", nameof(model.Password)); + } + _logger.LogInformation("Client. ClientFIO:{ClientFIO}. Email:{Email}. Id:{Id} ", model.ClientFIO, model.Email, model.Id); + + var element = _clientStorage.GetElement(new ClientSearchModel + { + Email = model.Email + }); + + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("User with such email already exists."); + } + } + } +} diff --git a/SewingDresses/SewingDressesContracts/BindingModels/ClientBindingModel.cs b/SewingDresses/SewingDressesContracts/BindingModels/ClientBindingModel.cs new file mode 100644 index 0000000..c0c9a73 --- /dev/null +++ b/SewingDresses/SewingDressesContracts/BindingModels/ClientBindingModel.cs @@ -0,0 +1,12 @@ +using SewingDressesDataModels.Models; + +namespace SewingDressesContracts.BindingModels +{ + public class ClientBindingModel : IClientModel + { + public int Id { get; set; } + public string ClientFIO { get; set; } = string.Empty; + public string Email { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + } +} diff --git a/SewingDresses/SewingDressesContracts/BindingModels/OrderBindingModel.cs b/SewingDresses/SewingDressesContracts/BindingModels/OrderBindingModel.cs index f92a526..0462f9a 100644 --- a/SewingDresses/SewingDressesContracts/BindingModels/OrderBindingModel.cs +++ b/SewingDresses/SewingDressesContracts/BindingModels/OrderBindingModel.cs @@ -7,6 +7,8 @@ namespace SewingDressesContracts.BindingModels { public int Id { get; set; } public int DressId { get; set; } + public int ClientId { get; set; } + public string ClientFIO { get; set; } = string.Empty; public int Count { get; set; } public double Sum { get; set; } public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; diff --git a/SewingDresses/SewingDressesContracts/BusinessLogicsContracts/IClientLogic.cs b/SewingDresses/SewingDressesContracts/BusinessLogicsContracts/IClientLogic.cs new file mode 100644 index 0000000..fe12e8a --- /dev/null +++ b/SewingDresses/SewingDressesContracts/BusinessLogicsContracts/IClientLogic.cs @@ -0,0 +1,15 @@ +using SewingDressesContracts.BindingModels; +using SewingDressesContracts.SearchModels; +using SewingDressesContracts.ViewModels; + +namespace SewingDressesContracts.BusinessLogicsContracts +{ + public interface IClientLogic + { + List? ReadList(ClientSearchModel? model); + ClientViewModel? ReadElement(ClientSearchModel model); + bool Create(ClientBindingModel model); + bool Update(ClientBindingModel model); + bool Delete(ClientBindingModel model); + } +} diff --git a/SewingDresses/SewingDressesContracts/SearchModels/ClientSearchModel.cs b/SewingDresses/SewingDressesContracts/SearchModels/ClientSearchModel.cs new file mode 100644 index 0000000..e8b3ee2 --- /dev/null +++ b/SewingDresses/SewingDressesContracts/SearchModels/ClientSearchModel.cs @@ -0,0 +1,8 @@ +namespace SewingDressesContracts.SearchModels +{ + public class ClientSearchModel + { + public int? Id { get; set; } + public string? Email { get; set; } + } +} diff --git a/SewingDresses/SewingDressesContracts/SearchModels/OrderSearchModel.cs b/SewingDresses/SewingDressesContracts/SearchModels/OrderSearchModel.cs index 083e9f5..cd22d81 100644 --- a/SewingDresses/SewingDressesContracts/SearchModels/OrderSearchModel.cs +++ b/SewingDresses/SewingDressesContracts/SearchModels/OrderSearchModel.cs @@ -3,6 +3,7 @@ public class OrderSearchModel { public int? Id { get; set; } + public int? ClientId { get; set; } public DateTime? DateFrom { get; set; } public DateTime? DateTo { get; set; } } diff --git a/SewingDresses/SewingDressesContracts/StoragesContracts/IClientStorage.cs b/SewingDresses/SewingDressesContracts/StoragesContracts/IClientStorage.cs new file mode 100644 index 0000000..5b00e5b --- /dev/null +++ b/SewingDresses/SewingDressesContracts/StoragesContracts/IClientStorage.cs @@ -0,0 +1,16 @@ +using SewingDressesContracts.BindingModels; +using SewingDressesContracts.SearchModels; +using SewingDressesContracts.ViewModels; + +namespace SewingDressesContracts.StoragesContracts +{ + public interface IClientStorage + { + List GetFullList(); + List GetFilteredList(ClientSearchModel model); + ClientViewModel? GetElement(ClientSearchModel model); + ClientViewModel? Insert(ClientBindingModel model); + ClientViewModel? Update(ClientBindingModel model); + ClientViewModel? Delete(ClientBindingModel model); + } +} diff --git a/SewingDresses/SewingDressesContracts/ViewModels/ClientViewModel.cs b/SewingDresses/SewingDressesContracts/ViewModels/ClientViewModel.cs new file mode 100644 index 0000000..68bad04 --- /dev/null +++ b/SewingDresses/SewingDressesContracts/ViewModels/ClientViewModel.cs @@ -0,0 +1,16 @@ +using System.ComponentModel; +using SewingDressesDataModels.Models; + +namespace SewingDressesContracts.ViewModels +{ + public class ClientViewModel : IClientModel + { + public int Id { get; set; } + [DisplayName("ФИО клиента")] + public string ClientFIO { get; set; } = string.Empty; + [DisplayName("Логин (эл. почта)")] + public string Email { get; set; } = string.Empty; + [DisplayName("Пароль")] + public string Password { get; set; } = string.Empty; + } +} diff --git a/SewingDresses/SewingDressesContracts/ViewModels/OrderViewModel.cs b/SewingDresses/SewingDressesContracts/ViewModels/OrderViewModel.cs index e61a9e7..ca74cf3 100644 --- a/SewingDresses/SewingDressesContracts/ViewModels/OrderViewModel.cs +++ b/SewingDresses/SewingDressesContracts/ViewModels/OrderViewModel.cs @@ -9,6 +9,9 @@ namespace SewingDressesContracts.ViewModels [DisplayName("Номер")] public int Id { get; set; } public int DressId { get; set; } + public int ClientId { get; set; } + [DisplayName("Имя клиента")] + public string ClientFIO { get; set; } = string.Empty; [DisplayName("Платье")] public string DressName { get; set; } = string.Empty; [DisplayName("Количество")] diff --git a/SewingDresses/SewingDressesDataModels/Models/IClientModel.cs b/SewingDresses/SewingDressesDataModels/Models/IClientModel.cs new file mode 100644 index 0000000..2c3d562 --- /dev/null +++ b/SewingDresses/SewingDressesDataModels/Models/IClientModel.cs @@ -0,0 +1,9 @@ +namespace SewingDressesDataModels.Models +{ + public interface IClientModel : IId + { + string ClientFIO { get; } + string Email { get; } + string Password { get; } + } +} diff --git a/SewingDresses/SewingDressesDatabaseImplement/Implements/ClientStorage.cs b/SewingDresses/SewingDressesDatabaseImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..78d4192 --- /dev/null +++ b/SewingDresses/SewingDressesDatabaseImplement/Implements/ClientStorage.cs @@ -0,0 +1,62 @@ +using SewingDressesContracts.BindingModels; +using SewingDressesContracts.SearchModels; +using SewingDressesContracts.StoragesContracts; +using SewingDressesContracts.ViewModels; +using SewingDressesDatabaseImplement.Models; + + +namespace SewingDressesDatabaseImplement.Implements +{ + public class ClientStorage : IClientStorage + { + public ClientViewModel? Insert(ClientBindingModel model) + { + using var context = new SewingDressesDatabase(); + var newClient = Client.Create(model); + if (newClient == null) { return null; } + context.Clients.Add(newClient); + context.SaveChanges(); + return newClient.GetViewModel; + } + + public ClientViewModel? Update(ClientBindingModel model) + { + using var context = new SewingDressesDatabase(); + var client = context.Clients.FirstOrDefault(x => x.ID == model.ID); + if (client == null) { return null; }; + client.Update(model); + context.SaveChanges(); + return client.GetViewModel; + } + + public ClientViewModel? Delete(ClientBindingModel model) + { + using var context = new SewingDressesDatabase(); + var client = context.Clients.FirstOrDefault(x => x.Id == model.Id); + if (client == null) { return null; } + context.Clients.Remove(client); + context.SaveChanges(); + return client.GetViewModel; + } + + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) { return null; } + using var context = new SewingDressesDatabase(); + return context.Clients.FirstOrDefault(x => (!(string.IsNullOrEmpty(model.Email)) && model.Email == x.Email) || (model.ID.HasValue && model.ID == x.ID))?.GetViewModel; + } + + public List GetFilteredList(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.Email)) { return new(); } + using var context = new SewingDressesDatabase(); + return context.Clients.Where(x => x.Email.Equals(model.Email)).Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() + { + using var context = new SewingDressesDatabase(); + return context.Clients.Select(x => x.GetViewModel).ToList(); + } + } +} diff --git a/SewingDresses/SewingDressesDatabaseImplement/Models/Client.cs b/SewingDresses/SewingDressesDatabaseImplement/Models/Client.cs new file mode 100644 index 0000000..1619e2d --- /dev/null +++ b/SewingDresses/SewingDressesDatabaseImplement/Models/Client.cs @@ -0,0 +1,54 @@ +using SewingDressesContracts.BindingModels; +using SewingDressesContracts.ViewModels; +using SewingDressesDatabaseImplement.Models; +using SewingDressesDataModels.Models; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace SewingDressesDatabaseImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; private set; } + [Required] + public string ClientFIO { get; private set; } = string.Empty; + [Required] + public string Email { get; private set; } = string.Empty; + [Required] + public string Password { get; private set; } = string.Empty; + + [ForeignKey("ClientId")] + public virtual List Orders { get; set; } = new(); + + public static Client? Create(ClientBindingModel? model) + { + if (model == null) + { + return null; + } + return new Client() + { + Id = model.Id, + ClientFIO = model.ClientFIO, + Email = model.Email, + Password = model.Password + }; + } + + public void Update(ClientBindingModel? model) + { + if (model == null) { return; } + ClientFIO = model.ClientFIO; + Email = model.Email; + Password = model.Password; + } + + public ClientViewModel GetViewModel => new() + { + Id = Id, + ClientFIO = ClientFIO, + Email = Email, + Password = Password + }; + } +} diff --git a/SewingDresses/SewingDressesDatabaseImplement/Models/Order.cs b/SewingDresses/SewingDressesDatabaseImplement/Models/Order.cs index c840c87..071f011 100644 --- a/SewingDresses/SewingDressesDatabaseImplement/Models/Order.cs +++ b/SewingDresses/SewingDressesDatabaseImplement/Models/Order.cs @@ -13,6 +13,8 @@ namespace SewingDressesDatabaseImplement.Models [Required] public int DressId { get; private set; } [Required] + public int ClientId { get; private set; } + [Required] public int Count { get; private set; } [Required] public double Sum { get; private set; } @@ -32,6 +34,7 @@ namespace SewingDressesDatabaseImplement.Models { Id = model.Id, DressId = model.DressId, + ClientId = Count = model.Count, Sum = model.Sum, Status = model.Status, diff --git a/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabase.cs b/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabase.cs index 7a4beb3..b0cc144 100644 --- a/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabase.cs +++ b/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabase.cs @@ -16,5 +16,6 @@ namespace SewingDressesDatabaseImplement public virtual DbSet Dresses { get; set; } public virtual DbSet DressComponents { get; set; } public virtual DbSet Orders { get; set; } + public virtual DbSet Clients { get; set; } } }