From 0870c015f51b1eff1dbfdb41cf9453f4775f0bd6 Mon Sep 17 00:00:00 2001 From: antoc0der <1@DESKTOP-K1L8ND3> Date: Sat, 6 Apr 2024 18:45:56 +0400 Subject: [PATCH] =?UTF-8?q?=D1=87=D1=83=D0=B4=D0=B5=D1=81=D0=BD=D0=BE))?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FlowerShopBusinessLogic/ClientLogic.cs | 121 ++++++++++++++++++ .../BindingModels/ClientBindingModel.cs | 17 +++ .../BindingModels/OrderBindingModel.cs | 2 + .../BusinessLogicsContracts/IClientLogic.cs | 21 +++ .../SearchModels/ClientSearchModel.cs | 15 +++ .../SearchModels/OrderSearchModel.cs | 2 + .../StoragesContracts/IClientStorage.cs | 21 +++ .../ViewModels/ClientViewModel.cs | 21 +++ .../ViewModels/OrderViewModel.cs | 3 + FlowerShopDataModels/IClientModel.cs | 15 +++ FlowerShopDataModels/IOrderModel.cs | 2 + FlowerShopDatabaseImplement/Client.cs | 69 ++++++++++ FlowerShopDatabaseImplement/ClientStorage.cs | 86 +++++++++++++ .../FlowerShopDataBase.cs | 2 + ... 20240406141822_InitialCreate.Designer.cs} | 53 +++++++- ...ate.cs => 20240406141822_InitialCreate.cs} | 32 ++++- .../FlowerShopDataBaseModelSnapshot.cs | 51 +++++++- FlowerShopDatabaseImplement/Order.cs | 6 + FlowerShopDatabaseImplement/OrderStorage.cs | 7 +- FlowerShopFileImplement/Client.cs | 73 +++++++++++ FlowerShopFileImplement/ClientStorage.cs | 85 ++++++++++++ FlowerShopFileImplement/DataFileSingleton.cs | 12 +- FlowerShopFileImplement/Order.cs | 7 + FlowerShopFileImplement/OrderStorage.cs | 13 +- FlowerShopListImplement/Client.cs | 50 ++++++++ FlowerShopListImplement/ClientStorage.cs | 104 +++++++++++++++ FlowerShopListImplement/DataListSingleton.cs | 4 + FlowerShopListImplement/Order.cs | 6 + FlowerShopListImplement/OrderStorage.cs | 12 +- .../Controllers/ClientController.cs | 65 ++++++++++ .../Controllers/WeatherForecastController.cs | 33 +++++ FlowerShopRestApi/FlowerShopRestApi.csproj | 19 +++ FlowerShopRestApi/Program.cs | 41 ++++++ .../Properties/launchSettings.json | 31 +++++ FlowerShopRestApi/WeatherForecast.cs | 13 ++ .../appsettings.Development.json | 8 ++ FlowerShopRestApi/appsettings.json | 9 ++ ProjectFlowerShop.sln | 8 +- 38 files changed, 1121 insertions(+), 18 deletions(-) create mode 100644 FlowerShopBusinessLogic/ClientLogic.cs create mode 100644 FlowerShopContracts/BindingModels/ClientBindingModel.cs create mode 100644 FlowerShopContracts/BusinessLogicsContracts/IClientLogic.cs create mode 100644 FlowerShopContracts/SearchModels/ClientSearchModel.cs create mode 100644 FlowerShopContracts/StoragesContracts/IClientStorage.cs create mode 100644 FlowerShopContracts/ViewModels/ClientViewModel.cs create mode 100644 FlowerShopDataModels/IClientModel.cs create mode 100644 FlowerShopDatabaseImplement/Client.cs create mode 100644 FlowerShopDatabaseImplement/ClientStorage.cs rename FlowerShopDatabaseImplement/Migrations/{20240312171524_InitialCreate.Designer.cs => 20240406141822_InitialCreate.Designer.cs} (75%) rename FlowerShopDatabaseImplement/Migrations/{20240312171524_InitialCreate.cs => 20240406141822_InitialCreate.cs} (79%) create mode 100644 FlowerShopFileImplement/Client.cs create mode 100644 FlowerShopFileImplement/ClientStorage.cs create mode 100644 FlowerShopListImplement/Client.cs create mode 100644 FlowerShopListImplement/ClientStorage.cs create mode 100644 FlowerShopRestApi/Controllers/ClientController.cs create mode 100644 FlowerShopRestApi/Controllers/WeatherForecastController.cs create mode 100644 FlowerShopRestApi/FlowerShopRestApi.csproj create mode 100644 FlowerShopRestApi/Program.cs create mode 100644 FlowerShopRestApi/Properties/launchSettings.json create mode 100644 FlowerShopRestApi/WeatherForecast.cs create mode 100644 FlowerShopRestApi/appsettings.Development.json create mode 100644 FlowerShopRestApi/appsettings.json diff --git a/FlowerShopBusinessLogic/ClientLogic.cs b/FlowerShopBusinessLogic/ClientLogic.cs new file mode 100644 index 0000000..09fbaff --- /dev/null +++ b/FlowerShopBusinessLogic/ClientLogic.cs @@ -0,0 +1,121 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.StoragesContracts; +using FlowerShopContracts.ViewModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlowerShopBusinessLogic.BusinessLogic +{ + public class ClientLogic : IClientLogic + { + private readonly ILogger _logger; + private readonly IClientStorage _clientStorage; + public ClientLogic(ILogger logger, IClientStorage componentStorage) + { + _logger = logger; + _clientStorage = componentStorage; + } + public List? ReadList(ClientSearchModel? model) + { + _logger.LogInformation("ReadList. ClientFIO:{ClientFIO}. Id:{ Id}", model?.ClientFIO, 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 ClientViewModel? ReadElement(ClientSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ClientFIO:{ClientFIO}.Id:{ Id}", model.ClientFIO, 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 bool Create(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + public bool Update(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Update(model) == null) + { + _logger.LogWarning("Update 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; + } + 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.Email)) + { + throw new ArgumentNullException("Нет Email клиента", + nameof(model.ClientFIO)); + } + if (string.IsNullOrEmpty(model.Password)) + { + throw new ArgumentNullException("Нет пароля клиента", + nameof(model.ClientFIO)); + } + _logger.LogInformation("Client. ClientFIO:{ClientFIO}." + + "Email:{ Email}. Password:{ Password}. Id: { Id} ", model.ClientFIO, model.Email, model.Password, model.Id); + var element = _clientStorage.GetElement(new ClientSearchModel + { + Email = model.Email, + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Клиент с таким лоигном уже есть"); + } + } + } +} diff --git a/FlowerShopContracts/BindingModels/ClientBindingModel.cs b/FlowerShopContracts/BindingModels/ClientBindingModel.cs new file mode 100644 index 0000000..64fd41c --- /dev/null +++ b/FlowerShopContracts/BindingModels/ClientBindingModel.cs @@ -0,0 +1,17 @@ +using FlowerShopDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlowerShopContracts.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/FlowerShopContracts/BindingModels/OrderBindingModel.cs b/FlowerShopContracts/BindingModels/OrderBindingModel.cs index 7b4ca77..64006fc 100644 --- a/FlowerShopContracts/BindingModels/OrderBindingModel.cs +++ b/FlowerShopContracts/BindingModels/OrderBindingModel.cs @@ -17,5 +17,7 @@ namespace FlowerShopContracts.BindingModels public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; public DateTime DateCreate { get; set; } = DateTime.Now; public DateTime? DateImplement { get; set; } + public int ClientId { get; set; } + } } diff --git a/FlowerShopContracts/BusinessLogicsContracts/IClientLogic.cs b/FlowerShopContracts/BusinessLogicsContracts/IClientLogic.cs new file mode 100644 index 0000000..f2a0948 --- /dev/null +++ b/FlowerShopContracts/BusinessLogicsContracts/IClientLogic.cs @@ -0,0 +1,21 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.ViewModels; +using FlowerShopContracts.SearchModels; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlowerShopContracts.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/FlowerShopContracts/SearchModels/ClientSearchModel.cs b/FlowerShopContracts/SearchModels/ClientSearchModel.cs new file mode 100644 index 0000000..78fca61 --- /dev/null +++ b/FlowerShopContracts/SearchModels/ClientSearchModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlowerShopContracts.SearchModels +{ + public class ClientSearchModel + { + public int? Id { get; set; } + public string? ClientFIO { get; set; } + public string? Email { get; set; } + } +} diff --git a/FlowerShopContracts/SearchModels/OrderSearchModel.cs b/FlowerShopContracts/SearchModels/OrderSearchModel.cs index c8cd5d3..7737f3f 100644 --- a/FlowerShopContracts/SearchModels/OrderSearchModel.cs +++ b/FlowerShopContracts/SearchModels/OrderSearchModel.cs @@ -11,5 +11,7 @@ namespace FlowerShopContracts.SearchModels public int? Id { get; set; } public DateTime? DateFrom { get; set; } public DateTime? DateTo { get; set; } + public int? ClientId { get; set; } + } } diff --git a/FlowerShopContracts/StoragesContracts/IClientStorage.cs b/FlowerShopContracts/StoragesContracts/IClientStorage.cs new file mode 100644 index 0000000..8920c60 --- /dev/null +++ b/FlowerShopContracts/StoragesContracts/IClientStorage.cs @@ -0,0 +1,21 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlowerShopContracts.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/FlowerShopContracts/ViewModels/ClientViewModel.cs b/FlowerShopContracts/ViewModels/ClientViewModel.cs new file mode 100644 index 0000000..79577d0 --- /dev/null +++ b/FlowerShopContracts/ViewModels/ClientViewModel.cs @@ -0,0 +1,21 @@ +using FlowerShopDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlowerShopContracts.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/FlowerShopContracts/ViewModels/OrderViewModel.cs b/FlowerShopContracts/ViewModels/OrderViewModel.cs index 3f04e8e..6044b89 100644 --- a/FlowerShopContracts/ViewModels/OrderViewModel.cs +++ b/FlowerShopContracts/ViewModels/OrderViewModel.cs @@ -26,5 +26,8 @@ namespace FlowerShopContracts.ViewModels public DateTime DateCreate { get; set; } = DateTime.Now; [DisplayName("Дата выполнения")] public DateTime? DateImplement { get; set; } + public int ClientId { get; set; } + [DisplayName("Клиент")] + public string ClientFIO { get; set; } = string.Empty; } } diff --git a/FlowerShopDataModels/IClientModel.cs b/FlowerShopDataModels/IClientModel.cs new file mode 100644 index 0000000..32fd369 --- /dev/null +++ b/FlowerShopDataModels/IClientModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlowerShopDataModels.Models +{ + public interface IClientModel : IId + { + string ClientFIO { get; } + string Email { get; } + string Password { get; } + } +} diff --git a/FlowerShopDataModels/IOrderModel.cs b/FlowerShopDataModels/IOrderModel.cs index 3251e08..3ecfb82 100644 --- a/FlowerShopDataModels/IOrderModel.cs +++ b/FlowerShopDataModels/IOrderModel.cs @@ -15,6 +15,8 @@ namespace FlowerShopDataModels OrderStatus Status { get; } DateTime DateCreate { get; } DateTime? DateImplement { get; } + int ClientId { get; } + } } diff --git a/FlowerShopDatabaseImplement/Client.cs b/FlowerShopDatabaseImplement/Client.cs new file mode 100644 index 0000000..fa27197 --- /dev/null +++ b/FlowerShopDatabaseImplement/Client.cs @@ -0,0 +1,69 @@ +using FlowerShopDataModels.Models; +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.ViewModels; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace FlowerShopDatabaseImplement.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; set; } = string.Empty; + [Required] + public string Password { get; 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 static Client Create(ClientViewModel model) + { + 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/FlowerShopDatabaseImplement/ClientStorage.cs b/FlowerShopDatabaseImplement/ClientStorage.cs new file mode 100644 index 0000000..8ab0205 --- /dev/null +++ b/FlowerShopDatabaseImplement/ClientStorage.cs @@ -0,0 +1,86 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.StoragesContracts; +using FlowerShopContracts.ViewModels; +using FlowerShopDatabaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlowerShopDatabaseImplement.Implements +{ + public class ClientStorage : IClientStorage + { + public List GetFullList() + { + using var context = new FlowerShopDataBase(); + return context.Clients + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email)) + { + return new(); + } + using var context = new FlowerShopDataBase(); + return context.Clients + .Where(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO.Contains(model.ClientFIO) && + (string.IsNullOrEmpty(model.Email) || x.ClientFIO.Contains(model.Email)))) + .Select(x => x.GetViewModel) + .ToList(); + } + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email) && + !model.Id.HasValue) + { + return null; + } + using var context = new FlowerShopDataBase(); + return context.Clients + .FirstOrDefault(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO == model.ClientFIO) && + (!model.Id.HasValue || x.Id == model.Id) && (string.IsNullOrEmpty(model.Email) || x.Email == model.Email)) + ?.GetViewModel; + } + public ClientViewModel? Insert(ClientBindingModel model) + { + var newClient = Client.Create(model); + if (newClient == null) + { + return null; + } + using var context = new FlowerShopDataBase(); + context.Clients.Add(newClient); + context.SaveChanges(); + return newClient.GetViewModel; + } + public ClientViewModel? Update(ClientBindingModel model) + { + using var context = new FlowerShopDataBase(); + 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 FlowerShopDataBase(); + var element = context.Clients.FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Clients.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/FlowerShopDatabaseImplement/FlowerShopDataBase.cs b/FlowerShopDatabaseImplement/FlowerShopDataBase.cs index 2dcffdc..1ff39cb 100644 --- a/FlowerShopDatabaseImplement/FlowerShopDataBase.cs +++ b/FlowerShopDatabaseImplement/FlowerShopDataBase.cs @@ -22,5 +22,7 @@ namespace FlowerShopDatabaseImplement public virtual DbSet Flowers { set; get; } public virtual DbSet FlowerComponents { set; get; } public virtual DbSet Orders { set; get; } + public virtual DbSet Clients { set; get; } + } } diff --git a/FlowerShopDatabaseImplement/Migrations/20240312171524_InitialCreate.Designer.cs b/FlowerShopDatabaseImplement/Migrations/20240406141822_InitialCreate.Designer.cs similarity index 75% rename from FlowerShopDatabaseImplement/Migrations/20240312171524_InitialCreate.Designer.cs rename to FlowerShopDatabaseImplement/Migrations/20240406141822_InitialCreate.Designer.cs index 4be73f1..eb13c94 100644 --- a/FlowerShopDatabaseImplement/Migrations/20240312171524_InitialCreate.Designer.cs +++ b/FlowerShopDatabaseImplement/Migrations/20240406141822_InitialCreate.Designer.cs @@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace FlowerShopDatabaseImplement.Migrations { [DbContext(typeof(FlowerShopDataBase))] - [Migration("20240312171524_InitialCreate")] + [Migration("20240406141822_InitialCreate")] partial class InitialCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -24,6 +24,31 @@ namespace FlowerShopDatabaseImplement.Migrations SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => { b.Property("Id") @@ -90,7 +115,7 @@ namespace FlowerShopDatabaseImplement.Migrations b.ToTable("FlowerComponents"); }); - modelBuilder.Entity("FlowerShopDatabaseImplement.Order", b => + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Order", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -98,6 +123,9 @@ namespace FlowerShopDatabaseImplement.Migrations SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + b.Property("ClientId") + .HasColumnType("int"); + b.Property("Count") .HasColumnType("int"); @@ -118,6 +146,8 @@ namespace FlowerShopDatabaseImplement.Migrations b.HasKey("Id"); + b.HasIndex("ClientId"); + b.HasIndex("FlowerId"); b.ToTable("Orders"); @@ -142,13 +172,28 @@ namespace FlowerShopDatabaseImplement.Migrations b.Navigation("Flower"); }); - modelBuilder.Entity("FlowerShopDatabaseImplement.Order", b => + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Order", b => { - b.HasOne("FlowerShopDatabaseImplement.Models.Flower", null) + b.HasOne("FlowerShopDatabaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("FlowerShopDatabaseImplement.Models.Flower", "Flower") .WithMany("Orders") .HasForeignKey("FlowerId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Client"); + + b.Navigation("Flower"); + }); + + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); }); modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => diff --git a/FlowerShopDatabaseImplement/Migrations/20240312171524_InitialCreate.cs b/FlowerShopDatabaseImplement/Migrations/20240406141822_InitialCreate.cs similarity index 79% rename from FlowerShopDatabaseImplement/Migrations/20240312171524_InitialCreate.cs rename to FlowerShopDatabaseImplement/Migrations/20240406141822_InitialCreate.cs index f2647dd..b6dd180 100644 --- a/FlowerShopDatabaseImplement/Migrations/20240312171524_InitialCreate.cs +++ b/FlowerShopDatabaseImplement/Migrations/20240406141822_InitialCreate.cs @@ -9,6 +9,21 @@ namespace FlowerShopDatabaseImplement.Migrations { protected override void Up(MigrationBuilder migrationBuilder) { + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ClientFIO = table.Column(type: "nvarchar(max)", nullable: false), + Email = table.Column(type: "nvarchar(max)", nullable: false), + Password = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clients", x => x.Id); + }); + migrationBuilder.CreateTable( name: "Components", columns: table => new @@ -75,11 +90,18 @@ namespace FlowerShopDatabaseImplement.Migrations Status = table.Column(type: "int", nullable: false), DateCreate = table.Column(type: "datetime2", nullable: false), DateImplement = table.Column(type: "datetime2", nullable: true), - FlowerId = table.Column(type: "int", nullable: false) + FlowerId = table.Column(type: "int", nullable: false), + ClientId = table.Column(type: "int", nullable: false) }, constraints: table => { table.PrimaryKey("PK_Orders", x => x.Id); + table.ForeignKey( + name: "FK_Orders_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "FK_Orders_Flowers_FlowerId", column: x => x.FlowerId, @@ -98,6 +120,11 @@ namespace FlowerShopDatabaseImplement.Migrations table: "FlowerComponents", column: "FlowerId"); + migrationBuilder.CreateIndex( + name: "IX_Orders_ClientId", + table: "Orders", + column: "ClientId"); + migrationBuilder.CreateIndex( name: "IX_Orders_FlowerId", table: "Orders", @@ -115,6 +142,9 @@ namespace FlowerShopDatabaseImplement.Migrations migrationBuilder.DropTable( name: "Components"); + migrationBuilder.DropTable( + name: "Clients"); + migrationBuilder.DropTable( name: "Flowers"); } diff --git a/FlowerShopDatabaseImplement/Migrations/FlowerShopDataBaseModelSnapshot.cs b/FlowerShopDatabaseImplement/Migrations/FlowerShopDataBaseModelSnapshot.cs index 75b6ac8..3d9e38f 100644 --- a/FlowerShopDatabaseImplement/Migrations/FlowerShopDataBaseModelSnapshot.cs +++ b/FlowerShopDatabaseImplement/Migrations/FlowerShopDataBaseModelSnapshot.cs @@ -22,6 +22,31 @@ namespace FlowerShopDatabaseImplement.Migrations SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => { b.Property("Id") @@ -88,7 +113,7 @@ namespace FlowerShopDatabaseImplement.Migrations b.ToTable("FlowerComponents"); }); - modelBuilder.Entity("FlowerShopDatabaseImplement.Order", b => + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Order", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -96,6 +121,9 @@ namespace FlowerShopDatabaseImplement.Migrations SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + b.Property("ClientId") + .HasColumnType("int"); + b.Property("Count") .HasColumnType("int"); @@ -116,6 +144,8 @@ namespace FlowerShopDatabaseImplement.Migrations b.HasKey("Id"); + b.HasIndex("ClientId"); + b.HasIndex("FlowerId"); b.ToTable("Orders"); @@ -140,13 +170,28 @@ namespace FlowerShopDatabaseImplement.Migrations b.Navigation("Flower"); }); - modelBuilder.Entity("FlowerShopDatabaseImplement.Order", b => + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Order", b => { - b.HasOne("FlowerShopDatabaseImplement.Models.Flower", null) + b.HasOne("FlowerShopDatabaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("FlowerShopDatabaseImplement.Models.Flower", "Flower") .WithMany("Orders") .HasForeignKey("FlowerId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Client"); + + b.Navigation("Flower"); + }); + + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); }); modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => diff --git a/FlowerShopDatabaseImplement/Order.cs b/FlowerShopDatabaseImplement/Order.cs index dc5f0b8..14974e5 100644 --- a/FlowerShopDatabaseImplement/Order.cs +++ b/FlowerShopDatabaseImplement/Order.cs @@ -27,6 +27,9 @@ namespace FlowerShopDatabaseImplement.Models public DateTime? DateImplement { get; private set; } [Required] public int FlowerId { get; private set; } + [Required] + public int ClientId { get; private set; } + public virtual Client? Client { get; private set; } public virtual Flower? Flower { get; set; } public static Order? Create(OrderBindingModel model) { @@ -43,6 +46,7 @@ namespace FlowerShopDatabaseImplement.Models DateCreate = model.DateCreate, DateImplement = model.DateImplement, FlowerId = model.FlowerId, + ClientId = model.ClientId, }; } @@ -62,10 +66,12 @@ namespace FlowerShopDatabaseImplement.Models Count = Count, Sum = Sum, Status = Status, + ClientId = ClientId, DateCreate = DateCreate, DateImplement = DateImplement, FlowerName = Flower?.FlowerName ?? String.Empty, Id = Id, + ClientFIO = Client.ClientFIO }; } diff --git a/FlowerShopDatabaseImplement/OrderStorage.cs b/FlowerShopDatabaseImplement/OrderStorage.cs index e510260..e51926c 100644 --- a/FlowerShopDatabaseImplement/OrderStorage.cs +++ b/FlowerShopDatabaseImplement/OrderStorage.cs @@ -41,7 +41,7 @@ namespace FlowerShopDatabaseImplement.Implements return null; } using var context = new FlowerShopDataBase(); - return context.Orders.Include(x => x.Flower).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel; + return context.Orders.Include(x => x.Flower).Include(x => x.Client).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel; } public OrderViewModel? Insert(OrderBindingModel model) { @@ -58,7 +58,7 @@ namespace FlowerShopDatabaseImplement.Implements public OrderViewModel? Update(OrderBindingModel model) { using var context = new FlowerShopDataBase(); - var order = context.Orders.Include(x => x.Flower).FirstOrDefault(x => x.Id == + var order = context.Orders.Include(x => x.Flower).Include(x => x.Client).FirstOrDefault(x => x.Id == model.Id); if (order == null) { @@ -71,8 +71,7 @@ namespace FlowerShopDatabaseImplement.Implements public OrderViewModel? Delete(OrderBindingModel model) { using var context = new FlowerShopDataBase(); - var element = context.Orders.Include(x => x.Flower).FirstOrDefault(rec => rec.Id == - model.Id); + var element = context.Orders.Include(x => x.Flower).Include(x => x.Client).FirstOrDefault(rec => rec.Id == model.Id); if (element != null) { context.Orders.Remove(element); diff --git a/FlowerShopFileImplement/Client.cs b/FlowerShopFileImplement/Client.cs new file mode 100644 index 0000000..337bd99 --- /dev/null +++ b/FlowerShopFileImplement/Client.cs @@ -0,0 +1,73 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.ViewModels; +using FlowerShopDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace FlowerShopFileImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; private set; } + public string ClientFIO { get; private set; } = string.Empty; + public string Email { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + 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 static Client? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Client() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ClientFIO = element.Element("ClientFIO")!.Value, + Email = element.Element("Email")!.Value, + Password = element.Element("Password")!.Value + }; + } + 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 + }; + + public XElement GetXElement => new("Client", + new XAttribute("Id", Id), + new XElement("ClientFIO", ClientFIO), + new XElement("Email", Email.ToString()), + new XElement("Password", Password.ToString()) + ); + } +} + diff --git a/FlowerShopFileImplement/ClientStorage.cs b/FlowerShopFileImplement/ClientStorage.cs new file mode 100644 index 0000000..68f9b3d --- /dev/null +++ b/FlowerShopFileImplement/ClientStorage.cs @@ -0,0 +1,85 @@ +using FlowerShopContracts.StoragesContracts; +using FlowerShopContracts.ViewModels; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.BindingModels; + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FlowerShopFileImplement.Models; + +namespace FlowerShopFileImplement.Implements +{ + public class ClientStorage : IClientStorage + { + private readonly DataFileSingleton source; + public ClientStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Clients + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ClientSearchModel + model) + { + if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email)) + { + return new(); + } + return source.Clients + .Where(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO.Contains(model.ClientFIO) && + (string.IsNullOrEmpty(model.Email) || x.ClientFIO.Contains(model.Email)))) + .Select(x => x.GetViewModel) + .ToList(); + } + public ClientViewModel? GetElement(ClientSearchModel model) + { + return source.Clients + .FirstOrDefault(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO == model.ClientFIO) && + (!model.Id.HasValue || x.Id == model.Id) && (string.IsNullOrEmpty(model.Email) || x.Email == model.Email)) + ?.GetViewModel; + } + public ClientViewModel? Insert(ClientBindingModel model) + { + model.Id = source.Clients.Count > 0 ? source.Clients.Max(x => + x.Id) + 1 : 1; + var newClient = Client.Create(model); + if (newClient == null) + { + return null; + } + source.Clients.Add(newClient); + source.SaveClients(); + return newClient.GetViewModel; + } + public ClientViewModel? Update(ClientBindingModel model) + { + var client = source.Clients.FirstOrDefault(x => x.Id == model.Id); + if (client == null) + { + return null; + } + client.Update(model); + source.SaveClients(); + return client.GetViewModel; + } + public ClientViewModel? Delete(ClientBindingModel model) + { + var element = source.Clients.FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + source.Clients.Remove(element); + source.SaveClients(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/FlowerShopFileImplement/DataFileSingleton.cs b/FlowerShopFileImplement/DataFileSingleton.cs index 83754aa..80175a7 100644 --- a/FlowerShopFileImplement/DataFileSingleton.cs +++ b/FlowerShopFileImplement/DataFileSingleton.cs @@ -9,9 +9,13 @@ internal class DataFileSingleton private readonly string ComponentFileName = "Component.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string FlowerFileName = "Product.xml"; + private readonly string ClientFileName = "Client.xml"; + public List Components { get; private set; } public List Orders { get; private set; } public List Flowers { get; private set; } + public List Clients { get; private set; } + public static DataFileSingleton GetInstance() { if (instance == null) @@ -26,11 +30,14 @@ internal class DataFileSingleton "Flowers", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); -private DataFileSingleton() + public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement); + private DataFileSingleton() { Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!; Flowers = LoadData(FlowerFileName, "Flower", x => Flower.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; + Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!; + } private static List? LoadData(string filename, string xmlNodeName, Func selectFunction) { @@ -41,8 +48,7 @@ private DataFileSingleton() } return new List(); } - private static void SaveData(List data, string filename, string - xmlNodeName, Func selectFunction) + private static void SaveData(List data, string filename, string xmlNodeName, Func selectFunction) { if (data != null) { diff --git a/FlowerShopFileImplement/Order.cs b/FlowerShopFileImplement/Order.cs index fde0ad5..fb2ffc7 100644 --- a/FlowerShopFileImplement/Order.cs +++ b/FlowerShopFileImplement/Order.cs @@ -15,6 +15,8 @@ namespace FlowerShopFileImplement.Models public OrderStatus Status { get; private set; } public DateTime DateCreate { get; private set; } public DateTime? DateImplement { get; private set; } + public int ClientId { get; private set; } + public static Order? Create(OrderBindingModel model) { @@ -31,6 +33,8 @@ namespace FlowerShopFileImplement.Models Status = model.Status, DateCreate = model.DateCreate, DateImplement = model.DateImplement, + ClientId = model.ClientId, + }; } public static Order? Create(XElement element) @@ -47,6 +51,7 @@ namespace FlowerShopFileImplement.Models Sum = Convert.ToDouble(element.Element("Sum")!.Value), Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value.ToString()), DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value), + ClientId = Convert.ToInt32(element.Element("ClientId")!.Value), DateImplement = string.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null : Convert.ToDateTime(element.Element("DateImplement")!.Value) }; } @@ -65,6 +70,7 @@ namespace FlowerShopFileImplement.Models FlowerId = FlowerId, Count = Count, Sum = Sum, + ClientId = ClientId, Status = Status, DateCreate = DateCreate, DateImplement = DateImplement, @@ -76,6 +82,7 @@ namespace FlowerShopFileImplement.Models new XElement("Count", Count), new XElement("Status", Status.ToString()), new XElement("DateCreate", DateCreate.ToString()), + new XElement("ClientId", ClientId), new XElement("DateImplement", DateImplement.ToString()) ); diff --git a/FlowerShopFileImplement/OrderStorage.cs b/FlowerShopFileImplement/OrderStorage.cs index 3419e98..09c6463 100644 --- a/FlowerShopFileImplement/OrderStorage.cs +++ b/FlowerShopFileImplement/OrderStorage.cs @@ -36,7 +36,8 @@ namespace FlowerShopFileImplement.Implements return source.Orders .Where(x => ((!model.Id.HasValue || x.Id == model.Id) && (!model.DateFrom.HasValue || x.DateCreate >= model.DateFrom) && - (!model.DateTo.HasValue || x.DateCreate <= model.DateTo))) + (!model.DateTo.HasValue || x.DateCreate <= model.DateTo) && + (!model.ClientId.HasValue || x.ClientId == model.ClientId))) .Select(x => AccessFlowerStorage(x.GetViewModel)) .ToList(); } @@ -102,5 +103,15 @@ namespace FlowerShopFileImplement.Implements return model; } + public OrderViewModel AccessClientStorage(OrderViewModel model) + { + if (model == null) + return null; + var client = source.Clients.FirstOrDefault(x => x.Id == model.Id); + if (client != null) + model.ClientFIO = client.ClientFIO; + return model; + } + } } diff --git a/FlowerShopListImplement/Client.cs b/FlowerShopListImplement/Client.cs new file mode 100644 index 0000000..030dd91 --- /dev/null +++ b/FlowerShopListImplement/Client.cs @@ -0,0 +1,50 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.ViewModels; +using FlowerShopDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlowerShopListImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; private set; } + public string ClientFIO { get; private set; } = string.Empty; + public string Email { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + 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/FlowerShopListImplement/ClientStorage.cs b/FlowerShopListImplement/ClientStorage.cs new file mode 100644 index 0000000..62251be --- /dev/null +++ b/FlowerShopListImplement/ClientStorage.cs @@ -0,0 +1,104 @@ +using FlowerShopContracts.StoragesContracts; +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.ViewModels; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FlowerShopListImplement.Models; + +namespace FlowerShopListImplement.Implements +{ + public class ClientStorage : IClientStorage + { + private readonly DataListSingleton _source; + public ClientStorage() + { + _source = DataListSingleton.GetInstance(); + } + public List GetFullList() + { + var result = new List(); + foreach (var client in _source.Clients) + { + result.Add(client.GetViewModel); + } + return result; + } + public List GetFilteredList(ClientSearchModel + model) + { + var result = new List(); + if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email)) + { + return result; + } + foreach (var client in _source.Clients) + { + if (client.ClientFIO.Contains(model.ClientFIO)) + { + result.Add(client.GetViewModel); + } + } + return result; + } + public ClientViewModel? GetElement(ClientSearchModel model) + { + foreach (var client in _source.Clients) + { + if ((string.IsNullOrEmpty(model.ClientFIO) || client.ClientFIO == model.ClientFIO) && + (!model.Id.HasValue || client.Id == model.Id) && (string.IsNullOrEmpty(model.Email) || client.Email == model.Email)) + { + return client.GetViewModel; + } + } + return null; + } + public ClientViewModel? Insert(ClientBindingModel model) + { + model.Id = 1; + foreach (var client in _source.Clients) + { + if (model.Id <= client.Id) + { + model.Id = client.Id + 1; + } + } + var newClient = Client.Create(model); + if (newClient == null) + { + return null; + } + _source.Clients.Add(newClient); + return newClient.GetViewModel; + } + public ClientViewModel? Update(ClientBindingModel model) + { + foreach (var client in _source.Clients) + { + if (client.Id == model.Id) + { + client.Update(model); + return client.GetViewModel; + } + } + return null; + } + public ClientViewModel? Delete(ClientBindingModel model) + { + for (int i = 0; i < _source.Clients.Count; ++i) + { + if (_source.Clients[i].Id == model.Id) + { + var element = _source.Clients[i]; + _source.Clients.RemoveAt(i); + return element.GetViewModel; + } + } + return null; + } + } +} diff --git a/FlowerShopListImplement/DataListSingleton.cs b/FlowerShopListImplement/DataListSingleton.cs index 117b155..35a183a 100644 --- a/FlowerShopListImplement/DataListSingleton.cs +++ b/FlowerShopListImplement/DataListSingleton.cs @@ -13,11 +13,14 @@ namespace FlowerShopListImplement public List Components { get; set; } public List Orders { get; set; } public List Flowers { get; set; } + public List Clients { get; set; } + private DataListSingleton() { Components = new List(); Orders = new List(); Flowers = new List(); + Clients = new List(); } public static DataListSingleton GetInstance() { @@ -27,5 +30,6 @@ namespace FlowerShopListImplement } return _instance; } + } } diff --git a/FlowerShopListImplement/Order.cs b/FlowerShopListImplement/Order.cs index 947b95a..c7dd233 100644 --- a/FlowerShopListImplement/Order.cs +++ b/FlowerShopListImplement/Order.cs @@ -16,6 +16,8 @@ namespace FlowerShopListImplement.Models public int FlowerId { get; private set; } public int Count { get; private set; } public double Sum { get; private set; } + public int ClientId { get; private set; } + public OrderStatus Status { get; private set; } public DateTime DateCreate { get; private set; } public DateTime? DateImplement { get; private set; } @@ -35,6 +37,8 @@ namespace FlowerShopListImplement.Models Status = model.Status, DateCreate = model.DateCreate, DateImplement = model.DateImplement, + ClientId = model.ClientId, + }; } public void Update(OrderBindingModel? model) @@ -46,6 +50,7 @@ namespace FlowerShopListImplement.Models Id = model.Id; FlowerId = model.FlowerId; Count = model.Count; + ClientId = model.ClientId; Sum = model.Sum; Status = model.Status; DateCreate = model.DateCreate; @@ -55,6 +60,7 @@ namespace FlowerShopListImplement.Models { Id = Id, FlowerId = FlowerId, + ClientId = ClientId, Count = Count, Sum = Sum, Status = Status, diff --git a/FlowerShopListImplement/OrderStorage.cs b/FlowerShopListImplement/OrderStorage.cs index 8a06835..0449aa0 100644 --- a/FlowerShopListImplement/OrderStorage.cs +++ b/FlowerShopListImplement/OrderStorage.cs @@ -37,7 +37,10 @@ namespace FlowerShopListImplement.Implements } foreach (var order in _source.Orders) { - if (order.Id == model.Id && model.DateFrom <= order.DateCreate && model.DateTo >= order.DateCreate) + if ((!model.Id.HasValue || order.Id == model.Id) && + (!model.DateFrom.HasValue || order.DateCreate >= model.DateFrom) && + (!model.DateTo.HasValue || order.DateCreate <= model.DateTo) && + (!model.ClientId.HasValue || order.ClientId == model.ClientId)) { result.Add(AccessFlowerStorage(order.GetViewModel)); } @@ -115,5 +118,12 @@ namespace FlowerShopListImplement.Implements } return model; } + public OrderViewModel AccessClientStorage(OrderViewModel model) + { + var client = _source.Clients.FirstOrDefault(x => x.Id == model.ClientId); + if (client != null) + model.ClientFIO = client.ClientFIO; + return model; + } } } diff --git a/FlowerShopRestApi/Controllers/ClientController.cs b/FlowerShopRestApi/Controllers/ClientController.cs new file mode 100644 index 0000000..f0d0f7d --- /dev/null +++ b/FlowerShopRestApi/Controllers/ClientController.cs @@ -0,0 +1,65 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace FlowerShopRestApi.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class ClientController : Controller + { + private readonly ILogger _logger; + private readonly IClientLogic _logic; + public ClientController(IClientLogic logic, ILogger + logger) + { + _logger = logger; + _logic = logic; + } + [HttpGet] + public ClientViewModel? Login(string login, string password) + { + try + { + return _logic.ReadElement(new ClientSearchModel + { + Email = login, + Password = password + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + [HttpPost] + public void Register(ClientBindingModel model) + { + try + { + _logic.Create(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка регистрации"); + throw; + } + } + [HttpPost] + public void UpdateData(ClientBindingModel model) + { + try + { + _logic.Update(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка обновления данных"); + throw; + } + } + } +} diff --git a/FlowerShopRestApi/Controllers/WeatherForecastController.cs b/FlowerShopRestApi/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..4b63d74 --- /dev/null +++ b/FlowerShopRestApi/Controllers/WeatherForecastController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; + +namespace FlowerShopRestApi.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} \ No newline at end of file diff --git a/FlowerShopRestApi/FlowerShopRestApi.csproj b/FlowerShopRestApi/FlowerShopRestApi.csproj new file mode 100644 index 0000000..e6ef66a --- /dev/null +++ b/FlowerShopRestApi/FlowerShopRestApi.csproj @@ -0,0 +1,19 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + diff --git a/FlowerShopRestApi/Program.cs b/FlowerShopRestApi/Program.cs new file mode 100644 index 0000000..e8a469c --- /dev/null +++ b/FlowerShopRestApi/Program.cs @@ -0,0 +1,41 @@ +using FlowerShopBusinessLogic.BusinessLogic; +using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.StoragesContracts; +using FlowerShopDatabaseImplement.Implements; +using Microsoft.OpenApi.Models; +var builder = WebApplication.CreateBuilder(args); +builder.Logging.SetMinimumLevel(LogLevel.Trace); +builder.Logging.AddLog4Net("log4net.config"); +// Add services to the container. +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at +https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(c => +{ + c.SwaggerDoc("v1", new OpenApiInfo + { + Title = "FlowerShopRestApi", + Version + = "v1" + }); +}); +var app = builder.Build(); +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", + "FlowerShopRestApi v1")); +} +app.UseHttpsRedirection(); +app.UseAuthorization(); +app.MapControllers(); +app.Run(); + diff --git a/FlowerShopRestApi/Properties/launchSettings.json b/FlowerShopRestApi/Properties/launchSettings.json new file mode 100644 index 0000000..445f7df --- /dev/null +++ b/FlowerShopRestApi/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:48724", + "sslPort": 44351 + } + }, + "profiles": { + "FlowerShopRestApi": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7213;http://localhost:5162", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/FlowerShopRestApi/WeatherForecast.cs b/FlowerShopRestApi/WeatherForecast.cs new file mode 100644 index 0000000..89e6125 --- /dev/null +++ b/FlowerShopRestApi/WeatherForecast.cs @@ -0,0 +1,13 @@ +namespace FlowerShopRestApi +{ + public class WeatherForecast + { + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } + } +} \ No newline at end of file diff --git a/FlowerShopRestApi/appsettings.Development.json b/FlowerShopRestApi/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/FlowerShopRestApi/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/FlowerShopRestApi/appsettings.json b/FlowerShopRestApi/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/FlowerShopRestApi/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/ProjectFlowerShop.sln b/ProjectFlowerShop.sln index eecfa72..164bad7 100644 --- a/ProjectFlowerShop.sln +++ b/ProjectFlowerShop.sln @@ -15,7 +15,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FlowerShopListImplement", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FlowerShopFileImplement", "FlowerShopFileImplement\FlowerShopFileImplement.csproj", "{0CFC7A18-2E56-4D0B-80AD-F52893222027}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlowerShopDatabaseImplement", "FlowerShopDatabaseImplement\FlowerShopDatabaseImplement.csproj", "{BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FlowerShopDatabaseImplement", "FlowerShopDatabaseImplement\FlowerShopDatabaseImplement.csproj", "{BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlowerShopRestApi", "FlowerShopRestApi\FlowerShopRestApi.csproj", "{729A747E-7DDA-4D6A-87C3-F83DCC6393F4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -51,6 +53,10 @@ Global {BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}.Debug|Any CPU.Build.0 = Debug|Any CPU {BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}.Release|Any CPU.ActiveCfg = Release|Any CPU {BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}.Release|Any CPU.Build.0 = Release|Any CPU + {729A747E-7DDA-4D6A-87C3-F83DCC6393F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {729A747E-7DDA-4D6A-87C3-F83DCC6393F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {729A747E-7DDA-4D6A-87C3-F83DCC6393F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {729A747E-7DDA-4D6A-87C3-F83DCC6393F4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE