diff --git a/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Implements/ClientStorage.cs b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..5fe8113 --- /dev/null +++ b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Implements/ClientStorage.cs @@ -0,0 +1,88 @@ +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.SearchModels; +using MotorPlantContracts.StoragesContracts; +using MotorPlantContracts.ViewModels; +using MotorPlantDatabaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantDatabaseImplement.Implements +{ + public class ClientStorage : IClientStorage + { + public List GetFullList() + { + using var context = new MotorPlantDatabase(); + return context.Clients + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email) && + string.IsNullOrEmpty(model.Password) && + string.IsNullOrEmpty(model.ClientFIO)) + { + return new(); + } + using var context = new MotorPlantDatabase(); + return context.Clients + .Where(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO.Contains(model.ClientFIO) && + string.IsNullOrEmpty(model.Email) || x.ClientFIO.Contains(model.Email) && + string.IsNullOrEmpty(model.Password) || x.ClientFIO.Contains(model.Password))) + .Select(x => x.GetViewModel) + .ToList(); + } + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.Email) && string.IsNullOrEmpty(model.Password) && !model.Id.HasValue) + { + return null; + } + using var context = new MotorPlantDatabase(); + return context.Clients.FirstOrDefault(x => + (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email && !string.IsNullOrEmpty(model.Password) && x.Password == model.Password) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + public ClientViewModel? Insert(ClientBindingModel model) + { + var newClient = Client.Create(model); + if (newClient == null) + { + return null; + } + using var context = new MotorPlantDatabase(); + context.Clients.Add(newClient); + context.SaveChanges(); + return newClient.GetViewModel; + } + public ClientViewModel? Update(ClientBindingModel model) + { + using var context = new MotorPlantDatabase(); + 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 MotorPlantDatabase(); + 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/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240326193537_InitialCreate.cs b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240326193537_InitialCreate.cs deleted file mode 100644 index d4d1f03..0000000 --- a/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240326193537_InitialCreate.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace MotorPlantDatabaseImplement.Migrations -{ - public partial class InitialCreate : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Components", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - ComponentName = table.Column(type: "nvarchar(max)", nullable: false), - Cost = table.Column(type: "float", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Components", x => x.Id); - }); - migrationBuilder.CreateTable( - name: "Engines", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - EngineName = table.Column(type: "nvarchar(max)", nullable: false), - Price = table.Column(type: "float", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Engines", x => x.Id); - }); - migrationBuilder.CreateTable( - name: "EngineComponents", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - EngineId = table.Column(type: "int", nullable: false), - ComponentId = table.Column(type: "int", nullable: false), - Count = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_EngineComponents", x => x.Id); - table.ForeignKey( - name: "FK_EngineComponents_Components_ComponentId", - column: x => x.ComponentId, - principalTable: "Components", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_EngineComponents_Engines_EngineId", - column: x => x.EngineId, - principalTable: "Engines", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - migrationBuilder.CreateTable( - name: "Orders", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - EngineId = table.Column(type: "int", nullable: false), - EngineName = table.Column(type: "nvarchar(max)", nullable: false), - Count = table.Column(type: "int", nullable: false), - Sum = table.Column(type: "float", nullable: false), - Status = table.Column(type: "int", nullable: false), - DateCreate = table.Column(type: "datetime2", nullable: false), - DateImplement = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Orders", x => x.Id); - table.ForeignKey( - name: "FK_Orders_Engines_EngineId", - column: x => x.EngineId, - principalTable: "Engines", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - migrationBuilder.CreateIndex( - name: "IX_EngineComponents_ComponentId", - table: "EngineComponents", - column: "ComponentId"); - migrationBuilder.CreateIndex( - name: "IX_EngineComponents_EngineId", - table: "EngineComponents", - column: "EngineId"); - migrationBuilder.CreateIndex( - name: "IX_Orders_EngineId", - table: "Orders", - column: "EngineId"); - } - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "EngineComponents"); - migrationBuilder.DropTable( - name: "Orders"); - migrationBuilder.DropTable( - name: "Components"); - migrationBuilder.DropTable( - name: "Engines"); - } - } -} diff --git a/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240326193537_InitialCreate.Designer.cs b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240501163500_Second.Designer.cs similarity index 79% rename from Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240326193537_InitialCreate.Designer.cs rename to Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240501163500_Second.Designer.cs index 7f05db6..571d444 100644 --- a/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240326193537_InitialCreate.Designer.cs +++ b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240501163500_Second.Designer.cs @@ -12,19 +12,44 @@ using MotorPlantDatabaseImplement; namespace MotorPlantDatabaseImplement.Migrations { [DbContext(typeof(MotorPlantDatabase))] - [Migration("20240326193537_InitialCreate")] - partial class InitialCreate + [Migration("20240501163500_Second")] + partial class Second { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("ProductVersion", "8.0.2") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + 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("MotorPlantDatabaseImplement.Models.Component", b => { b.Property("Id") @@ -99,6 +124,9 @@ namespace MotorPlantDatabaseImplement.Migrations SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("ClientId") + .HasColumnType("int"); + b.Property("Count") .HasColumnType("int"); @@ -123,6 +151,8 @@ namespace MotorPlantDatabaseImplement.Migrations b.HasKey("Id"); + b.HasIndex("ClientId"); + b.HasIndex("EngineId"); b.ToTable("Orders"); @@ -149,6 +179,10 @@ namespace MotorPlantDatabaseImplement.Migrations modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Order", b => { + b.HasOne("MotorPlantDatabaseImplement.Models.Client", null) + .WithMany("Orders") + .HasForeignKey("ClientId"); + b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine") .WithMany("Orders") .HasForeignKey("EngineId") @@ -158,6 +192,11 @@ namespace MotorPlantDatabaseImplement.Migrations b.Navigation("Engine"); }); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b => { b.Navigation("EngineComponents"); diff --git a/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240501163500_Second.cs b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240501163500_Second.cs new file mode 100644 index 0000000..5aa6e94 --- /dev/null +++ b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/20240501163500_Second.cs @@ -0,0 +1,66 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MotorPlantDatabaseImplement.Migrations +{ + /// + public partial class Second : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ClientId", + table: "Orders", + type: "int", + nullable: true); + + 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.CreateIndex( + name: "IX_Orders_ClientId", + table: "Orders", + column: "ClientId"); + + migrationBuilder.AddForeignKey( + name: "FK_Orders_Clients_ClientId", + table: "Orders", + column: "ClientId", + principalTable: "Clients", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Orders_Clients_ClientId", + table: "Orders"); + + migrationBuilder.DropTable( + name: "Clients"); + + migrationBuilder.DropIndex( + name: "IX_Orders_ClientId", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "ClientId", + table: "Orders"); + } + } +} diff --git a/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/MotorPlantDatabaseModelSnapshot.cs b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/MotorPlantDatabaseModelSnapshot.cs index aed8c70..d0f2463 100644 --- a/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/MotorPlantDatabaseModelSnapshot.cs +++ b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Migrations/MotorPlantDatabaseModelSnapshot.cs @@ -1,5 +1,13 @@ -using Microsoft.EntityFrameworkCore; +// +using System; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MotorPlantDatabaseImplement; + +#nullable disable + namespace MotorPlantDatabaseImplement.Migrations { [DbContext(typeof(MotorPlantDatabase))] @@ -7,11 +15,38 @@ namespace MotorPlantDatabaseImplement.Migrations { protected override void BuildModel(ModelBuilder modelBuilder) { +#pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("ProductVersion", "8.0.2") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + 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("MotorPlantDatabaseImplement.Models.Component", b => { b.Property("Id") @@ -31,62 +66,95 @@ namespace MotorPlantDatabaseImplement.Migrations b.ToTable("Components"); }); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Engine", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("EngineName") .IsRequired() .HasColumnType("nvarchar(max)"); + b.Property("Price") .HasColumnType("float"); + b.HasKey("Id"); + b.ToTable("Engines"); }); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("ComponentId") .HasColumnType("int"); + b.Property("Count") .HasColumnType("int"); + b.Property("EngineId") .HasColumnType("int"); + b.HasKey("Id"); + b.HasIndex("ComponentId"); + b.HasIndex("EngineId"); + b.ToTable("EngineComponents"); }); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Order", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClientId") + .HasColumnType("int"); + b.Property("Count") .HasColumnType("int"); + b.Property("DateCreate") .HasColumnType("datetime2"); + b.Property("DateImplement") .HasColumnType("datetime2"); + b.Property("EngineId") .HasColumnType("int"); + b.Property("EngineName") .IsRequired() .HasColumnType("nvarchar(max)"); + b.Property("Status") .HasColumnType("int"); + b.Property("Sum") .HasColumnType("float"); + b.HasKey("Id"); + + b.HasIndex("ClientId"); + b.HasIndex("EngineId"); + b.ToTable("Orders"); }); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b => { b.HasOne("MotorPlantDatabaseImplement.Models.Component", "Component") @@ -94,32 +162,50 @@ namespace MotorPlantDatabaseImplement.Migrations .HasForeignKey("ComponentId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine") .WithMany("Components") .HasForeignKey("EngineId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.Navigation("Component"); + b.Navigation("Engine"); }); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Order", b => { + b.HasOne("MotorPlantDatabaseImplement.Models.Client", null) + .WithMany("Orders") + .HasForeignKey("ClientId"); + b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine") .WithMany("Orders") .HasForeignKey("EngineId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.Navigation("Engine"); }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b => { b.Navigation("EngineComponents"); }); + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Engine", b => { b.Navigation("Components"); + b.Navigation("Orders"); }); +#pragma warning restore 612, 618 } } } diff --git a/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Models/Client.cs b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Models/Client.cs new file mode 100644 index 0000000..715dec8 --- /dev/null +++ b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/Models/Client.cs @@ -0,0 +1,67 @@ +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.ViewModels; +using MotorPlantDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantDatabaseImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; private set; } + [Required] + public string ClientFIO { get; 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/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/MotorPlantDatabase.cs b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/MotorPlantDatabase.cs index 8990935..439c225 100644 --- a/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/MotorPlantDatabase.cs +++ b/Aparyan.ISE_22.MotorPlant/MotorPlantDatabaseImplement/MotorPlantDatabase.cs @@ -9,7 +9,7 @@ namespace MotorPlantDatabaseImplement { if (optionsBuilder.IsConfigured == false) { - optionsBuilder.UseSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=master;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False"); + optionsBuilder.UseSqlServer(@"Data Source=WIN-QKNE49D1RUQ\SQLEXPRESS;Initial Catalog=MotorPlantDatabaseeses;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); } base.OnConfiguring(optionsBuilder); } @@ -17,5 +17,7 @@ namespace MotorPlantDatabaseImplement public virtual DbSet Engines { set; get; } public virtual DbSet EngineComponents { set; get; } public virtual DbSet Orders { set; get; } + public virtual DbSet Clients { set; get; } + } } diff --git a/MoorPlantListImplement/DataListSingleton.cs b/MoorPlantListImplement/DataListSingleton.cs index bf19afc..1db5f4b 100644 --- a/MoorPlantListImplement/DataListSingleton.cs +++ b/MoorPlantListImplement/DataListSingleton.cs @@ -7,6 +7,8 @@ namespace MotorPlantListImplement public List Components { get; set; } public List Orders { get; set; } public List Engines { get; set; } + public List Clients { get; set; } + private DataListSingleton() { Components = new List(); diff --git a/MoorPlantListImplement/Implements/ClientStorage.cs b/MoorPlantListImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..e4de804 --- /dev/null +++ b/MoorPlantListImplement/Implements/ClientStorage.cs @@ -0,0 +1,99 @@ +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.SearchModels; +using MotorPlantContracts.StoragesContracts; +using MotorPlantContracts.ViewModels; +using MotorPlantListImplement.Models; + +namespace MotorPlantListImplement.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) && string.IsNullOrEmpty(model.Password)) + { + 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) && + (string.IsNullOrEmpty(model.Password) || client.Password == model.Password)) + { + 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/MoorPlantListImplement/Models/Client.cs b/MoorPlantListImplement/Models/Client.cs new file mode 100644 index 0000000..8abb634 --- /dev/null +++ b/MoorPlantListImplement/Models/Client.cs @@ -0,0 +1,52 @@ +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.ViewModels; +using MotorPlantDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantListImplement.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/MotorPlantBusinessLogic/BusinessLogics/ClientLogic.cs b/MotorPlantBusinessLogic/BusinessLogics/ClientLogic.cs new file mode 100644 index 0000000..79e3d8e --- /dev/null +++ b/MotorPlantBusinessLogic/BusinessLogics/ClientLogic.cs @@ -0,0 +1,121 @@ +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.BusinessLogicsContracts; +using MotorPlantContracts.SearchModels; +using MotorPlantContracts.StoragesContracts; +using MotorPlantContracts.ViewModels; +using Microsoft.Extensions.Logging; + + +namespace MotorPlantBusinessLogic.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. ClientId:{Id}", 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/MotorPlantContracts/BindingModels/ClientBindingModel.cs b/MotorPlantContracts/BindingModels/ClientBindingModel.cs new file mode 100644 index 0000000..198a8c5 --- /dev/null +++ b/MotorPlantContracts/BindingModels/ClientBindingModel.cs @@ -0,0 +1,12 @@ +using MotorPlantDataModels.Models; + +namespace MotorPlantContracts.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/MotorPlantContracts/BusinessLogicsContracts/IClientLogic.cs b/MotorPlantContracts/BusinessLogicsContracts/IClientLogic.cs new file mode 100644 index 0000000..542d982 --- /dev/null +++ b/MotorPlantContracts/BusinessLogicsContracts/IClientLogic.cs @@ -0,0 +1,15 @@ +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.ViewModels; +using MotorPlantContracts.SearchModels; + +namespace MotorPlantContracts.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/MotorPlantContracts/SearchModels/ClientSearchModel.cs b/MotorPlantContracts/SearchModels/ClientSearchModel.cs new file mode 100644 index 0000000..833cedd --- /dev/null +++ b/MotorPlantContracts/SearchModels/ClientSearchModel.cs @@ -0,0 +1,10 @@ +namespace MotorPlantContracts.SearchModels +{ + public class ClientSearchModel + { + public int? Id { get; set; } + public string? ClientFIO { get; set; } + public string? Email { get; set; } + public string? Password { get; set; } + } +} diff --git a/MotorPlantContracts/StoragesContracts/IClientStorage.cs b/MotorPlantContracts/StoragesContracts/IClientStorage.cs new file mode 100644 index 0000000..1cbd79a --- /dev/null +++ b/MotorPlantContracts/StoragesContracts/IClientStorage.cs @@ -0,0 +1,16 @@ +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.SearchModels; +using MotorPlantContracts.ViewModels; + +namespace MotorPlantContracts.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/MotorPlantContracts/ViewModels/ClientViewModel.cs b/MotorPlantContracts/ViewModels/ClientViewModel.cs new file mode 100644 index 0000000..23522b8 --- /dev/null +++ b/MotorPlantContracts/ViewModels/ClientViewModel.cs @@ -0,0 +1,16 @@ +using MotorPlantDataModels.Models; +using System.ComponentModel; + +namespace MotorPlantContracts.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/MotorPlantDataModels/Models/IClientModel.cs b/MotorPlantDataModels/Models/IClientModel.cs new file mode 100644 index 0000000..3516e0d --- /dev/null +++ b/MotorPlantDataModels/Models/IClientModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantDataModels.Models +{ + public interface IClientModel : IId + { + string ClientFIO { get; } + string Email { get; } + string Password { get; } + } +} diff --git a/MotorPlantFileImplement/DataFileSingleton.cs b/MotorPlantFileImplement/DataFileSingleton.cs index 4e5a998..f655ef1 100644 --- a/MotorPlantFileImplement/DataFileSingleton.cs +++ b/MotorPlantFileImplement/DataFileSingleton.cs @@ -8,9 +8,13 @@ namespace MotorPlantFileImplement private readonly string ComponentFileName = "Component.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string EngineFileName = "Engine.xml"; + private readonly string ClientFileName = "Client.xml"; + public List Components { get; private set; } public List Orders { get; private set; } public List Engines { get; private set; } + public List Clients { get; private set; } + public static DataFileSingleton GetInstance() { @@ -23,6 +27,8 @@ namespace MotorPlantFileImplement public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); public void SaveEngines() => SaveData(Engines, EngineFileName, "Engines", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement); + private DataFileSingleton() { Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!; diff --git a/MotorPlantFileImplement/Implements/ClientStorage.cs b/MotorPlantFileImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..bba2b63 --- /dev/null +++ b/MotorPlantFileImplement/Implements/ClientStorage.cs @@ -0,0 +1,82 @@ +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.SearchModels; +using MotorPlantContracts.StoragesContracts; +using MotorPlantContracts.ViewModels; +using MotorPlantFileImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantFileImplement.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.Email)) + { + return new(); + } + return source.Clients.Where(x => x.Email.Contains(model.Email)).Select(x => x.GetViewModel).ToList(); + } + + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) + { + return null; + } + return source.Clients + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email) || + (model.Id.HasValue && x.Id == model.Id))?.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 ingredient = source.Clients.FirstOrDefault(x => x.Id == model.Id); + if (ingredient == null) + { + return null; + } + ingredient.Update(model); + source.SaveClients(); + return ingredient.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/MotorPlantFileImplement/Models/Client.cs b/MotorPlantFileImplement/Models/Client.cs new file mode 100644 index 0000000..660f75d --- /dev/null +++ b/MotorPlantFileImplement/Models/Client.cs @@ -0,0 +1,73 @@ +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.ViewModels; +using MotorPlantDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace MotorPlantFileImplement.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/MotorPlantView/FormClients.Designer.cs b/MotorPlantView/FormClients.Designer.cs new file mode 100644 index 0000000..53ea456 --- /dev/null +++ b/MotorPlantView/FormClients.Designer.cs @@ -0,0 +1,74 @@ +namespace MotorPlantView.Forms +{ + partial class FormClients + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + DataGridView = new DataGridView(); + DeleteButton = new Button(); + ((System.ComponentModel.ISupportInitialize)DataGridView).BeginInit(); + SuspendLayout(); + // + // DataGridView + // + DataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; + DataGridView.Location = new Point(12, 34); + DataGridView.Name = "DataGridView"; + DataGridView.RowTemplate.Height = 25; + DataGridView.Size = new Size(776, 404); + DataGridView.TabIndex = 0; + // + // DeleteButton + // + DeleteButton.Location = new Point(12, 5); + DeleteButton.Name = "DeleteButton"; + DeleteButton.Size = new Size(123, 23); + DeleteButton.TabIndex = 1; + DeleteButton.Text = "Удалить"; + DeleteButton.UseVisualStyleBackColor = true; + DeleteButton.Click += DeleteButton_Click; + // + // ClientsForm + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(DeleteButton); + Controls.Add(DataGridView); + Name = "ClientsForm"; + Text = "Клиенты"; + Load += ClientsForm_Load; + ((System.ComponentModel.ISupportInitialize)DataGridView).EndInit(); + ResumeLayout(false); + } + + #endregion + + private DataGridView DataGridView; + private Button DeleteButton; + } +} \ No newline at end of file diff --git a/MotorPlantView/FormClients.cs b/MotorPlantView/FormClients.cs new file mode 100644 index 0000000..68b6851 --- /dev/null +++ b/MotorPlantView/FormClients.cs @@ -0,0 +1,74 @@ +using Microsoft.Extensions.Logging; +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.BusinessLogicsContracts; +using System.Windows.Forms; + + +namespace MotorPlantView.Forms +{ + public partial class FormClients : Form + { + private readonly ILogger _logger; + private readonly IClientLogic _logic; + public FormClients(ILogger logger, IClientLogic logic) + { + InitializeComponent(); + _logger = logger; + _logic = logic; + } + + private void LoadData() + { + try + { + var list = _logic.ReadList(null); + if (list != null) + { + DataGridView.DataSource = list; + DataGridView.Columns["Id"].Visible = false; + DataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + } + _logger.LogInformation("Загрузка клиентов"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки клиентов"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + private void ClientsForm_Load(object sender, EventArgs e) + { + LoadData(); + } + private void DeleteButton_Click(object sender, EventArgs e) + { + if (DataGridView.SelectedRows.Count == 1) + { + if (MessageBox.Show("Удалить запись?", "Вопрос", + MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + int id = + Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Удаление клиента"); + try + { + if (!_logic.Delete(new ClientBindingModel + { + Id = id + })) + { + throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка удаления компонента"); + MessageBox.Show(ex.Message, "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } + } +} diff --git a/MotorPlantView/FormClients.resx b/MotorPlantView/FormClients.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/MotorPlantView/FormClients.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MotorPlantView/Program.cs b/MotorPlantView/Program.cs index 04280e8..7857b79 100644 --- a/MotorPlantView/Program.cs +++ b/MotorPlantView/Program.cs @@ -38,10 +38,12 @@ namespace MotorPlantView.Forms option.SetMinimumLevel(LogLevel.Information); option.AddNLog("nlog.config"); }); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -59,6 +61,8 @@ namespace MotorPlantView.Forms services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + } } } \ No newline at end of file