From 694f635d2f8224ef3972d0b6473b3bc818253d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9?= Date: Mon, 10 Apr 2023 01:33:54 +0400 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=81=D1=91=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FoodOrders/FoodOrders/FormMain.cs | 1 + FoodOrders/FoodOrders/Program.cs | 2 + .../BusinessLogics/ImplementerLogic.cs | 100 ++++++++++++++++-- .../BusinessLogics/WorkModeling.cs | 3 +- .../ViewModels/OrderViewModel.cs | 2 + .../FoodOrdersDatabase.cs | 2 +- .../Implements/OrderStorage.cs | 21 +++- ...igner.cs => 20230409213338_6b.Designer.cs} | 47 +++++++- ...09151800_5Base.cs => 20230409213338_6b.cs} | 32 +++++- .../FoodOrdersDatabaseModelSnapshot.cs | 43 ++++++++ .../Models/Order.cs | 3 + .../FoodOrdersFileImplement/Models/Order.cs | 1 + .../FoodOrdersListImplement/Models/Order.cs | 1 + 13 files changed, 245 insertions(+), 13 deletions(-) rename FoodOrders/FoodOrdersDatabaseImplement/Migrations/{20230409151800_5Base.Designer.cs => 20230409213338_6b.Designer.cs} (82%) rename FoodOrders/FoodOrdersDatabaseImplement/Migrations/{20230409151800_5Base.cs => 20230409213338_6b.cs} (81%) diff --git a/FoodOrders/FoodOrders/FormMain.cs b/FoodOrders/FoodOrders/FormMain.cs index 0ec0296..1ad0479 100644 --- a/FoodOrders/FoodOrders/FormMain.cs +++ b/FoodOrders/FoodOrders/FormMain.cs @@ -34,6 +34,7 @@ namespace FoodOrdersView dataGridView.DataSource = list; dataGridView.Columns["DishId"].Visible = false; dataGridView.Columns["ClientId"].Visible = false; + dataGridView.Columns["ImplementerId"].Visible = false; } _logger.LogInformation("Загрузка заказов"); } diff --git a/FoodOrders/FoodOrders/Program.cs b/FoodOrders/FoodOrders/Program.cs index 3c46cc9..87c7c58 100644 --- a/FoodOrders/FoodOrders/Program.cs +++ b/FoodOrders/FoodOrders/Program.cs @@ -69,6 +69,8 @@ namespace FoodOrdersView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file diff --git a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ImplementerLogic.cs b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ImplementerLogic.cs index 8c40798..79f3c08 100644 --- a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ImplementerLogic.cs +++ b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/ImplementerLogic.cs @@ -1,35 +1,123 @@ using FoodOrdersContracts.BindingModels; using FoodOrdersContracts.BusinessLogicsContracts; using FoodOrdersContracts.SearchModels; +using FoodOrdersContracts.StoragesContracts; using FoodOrdersContracts.ViewModels; +using Microsoft.Extensions.Logging; namespace FoodOrdersBusinessLogic.BusinessLogics { public class ImplementerLogic : IImplementerLogic { + private readonly ILogger _logger; + private readonly IImplementerStorage _implementerStorage; + public ImplementerLogic(ILogger logger, IImplementerStorage implementerStorage) + { + _logger = logger; + _implementerStorage = implementerStorage; + } + public bool Create(ImplementerBindingModel model) { - throw new NotImplementedException(); + CheckModel(model); + if (_implementerStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; } public bool Delete(ImplementerBindingModel model) { - throw new NotImplementedException(); + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_implementerStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; } public ImplementerViewModel? ReadElement(ImplementerSearchModel model) { - throw new NotImplementedException(); + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. FIO:{FIO}.Id:{ Id}", + model.ImplementerFIO, model.Id); + var element = _implementerStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; } public List? ReadList(ImplementerSearchModel? model) { - throw new NotImplementedException(); + _logger.LogInformation("ReadList. FIO:{FIO}.Id:{ Id} ", model?.ImplementerFIO, model?.Id); + var list = (model == null) ? _implementerStorage.GetFullList() : + _implementerStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; } public bool Update(ImplementerBindingModel model) { - throw new NotImplementedException(); + CheckModel(model); + if (_implementerStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + + private void CheckModel(ImplementerBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (model.WorkExperience < 0) + { + throw new ArgumentException("Опыт работы не должен быть отрицательным", nameof(model.WorkExperience)); + } + if (model.Qualification < 0) + { + throw new ArgumentException("Квалификация не должна быть отрицательной", nameof(model.Qualification)); + } + if (string.IsNullOrEmpty(model.Password)) + { + throw new ArgumentNullException("Нет пароля исполнителя", nameof(model.ImplementerFIO)); + } + if (string.IsNullOrEmpty(model.ImplementerFIO)) + { + throw new ArgumentNullException("Нет фио исполнителя", nameof(model.ImplementerFIO)); + } + _logger.LogInformation("Implementer. Id: {Id}, FIO: {FIO}", model.Id, model.ImplementerFIO); + var element = _implementerStorage.GetElement(new ImplementerSearchModel + { + ImplementerFIO = model.ImplementerFIO, + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Исполнитель с таким фио уже есть"); + } } } -} \ No newline at end of file +} diff --git a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/WorkModeling.cs b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/WorkModeling.cs index 41ff742..893af9e 100644 --- a/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/WorkModeling.cs +++ b/FoodOrders/FoodOrdersBusinessLogic/BusinessLogics/WorkModeling.cs @@ -74,7 +74,8 @@ namespace FoodOrdersBusinessLogic.BusinessLogics _logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id); _orderLogic.FinishOrder(new OrderBindingModel { - Id = order.Id + Id = order.Id, + ImplementerId = implementer.Id }); } // кто-то мог уже перехватить заказ, игнорируем ошибку diff --git a/FoodOrders/FoodOrdersContracts/ViewModels/OrderViewModel.cs b/FoodOrders/FoodOrdersContracts/ViewModels/OrderViewModel.cs index 286292b..ea1be3b 100644 --- a/FoodOrders/FoodOrdersContracts/ViewModels/OrderViewModel.cs +++ b/FoodOrders/FoodOrdersContracts/ViewModels/OrderViewModel.cs @@ -19,6 +19,8 @@ namespace FoodOrdersContracts.ViewModels public string ClientFIO { get; set; } = string.Empty; [DisplayName("Исполнитель")] + public string ImplementerFIO { get; set; } = string.Empty; + public int? ImplementerId { get; set; } [DisplayName("Количество")] diff --git a/FoodOrders/FoodOrdersDatabaseImplement/FoodOrdersDatabase.cs b/FoodOrders/FoodOrdersDatabaseImplement/FoodOrdersDatabase.cs index f166d55..ed15691 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/FoodOrdersDatabase.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/FoodOrdersDatabase.cs @@ -9,7 +9,7 @@ namespace FoodOrdersDatabaseImplement { if (optionsBuilder.IsConfigured == false) { - optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-SINQU55\SQLEXPRESS;Initial Catalog=FoodOrdersDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-SINQU55\SQLEXPRESS;Initial Catalog=FoodOrdersDatabase1;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); } base.OnConfiguring(optionsBuilder); } diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Implements/OrderStorage.cs b/FoodOrders/FoodOrdersDatabaseImplement/Implements/OrderStorage.cs index fdfae89..2c4e7eb 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/Implements/OrderStorage.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/Implements/OrderStorage.cs @@ -15,13 +15,14 @@ namespace FoodOrdersDatabaseImplement.Implements return context.Orders .Include(x => x.Dish) .Include(x => x.Client) + .Include(x => x.Implementer) .Select(x => x.GetViewModel) .ToList(); } public List GetFilteredList(OrderSearchModel model) { - if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.ClientId.HasValue) + if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.ClientId.HasValue && !model.Status.HasValue) { return new(); } @@ -31,6 +32,7 @@ namespace FoodOrdersDatabaseImplement.Implements return context.Orders .Include(x => x.Dish) .Include(x => x.Client) + .Include(x => x.Implementer) .Where(x => x.ClientId == model.ClientId) .Select(x => x.GetViewModel) .ToList(); @@ -39,14 +41,26 @@ namespace FoodOrdersDatabaseImplement.Implements { return context.Orders .Include(x => x.Dish) - .Include(x => x.Client) + .Include(x => x.Client) + .Include(x => x.Implementer) .Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) .Select(x => x.GetViewModel) .ToList(); } + else if (model.Status != null) + { + return context.Orders + .Include(x => x.Dish) + .Include(x => x.Client) + .Include(x => x.Implementer) + .Where(x => model.Status == x.Status) + .Select(x => x.GetViewModel) + .ToList(); ; + } return context.Orders .Include(x => x.Dish) .Include(x => x.Client) + .Include(x => x.Implementer) .Where(x => x.Id == model.Id) .Select(x => x.GetViewModel) .ToList(); @@ -62,6 +76,7 @@ namespace FoodOrdersDatabaseImplement.Implements return context.Orders .Include(x => x.Dish) .Include(x => x.Client) + .Include(x => x.Implementer) .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) ?.GetViewModel; } @@ -79,6 +94,7 @@ namespace FoodOrdersDatabaseImplement.Implements return context.Orders .Include(x => x.Dish) .Include(x => x.Client) + .Include(x => x.Implementer) .FirstOrDefault(x => x.Id == newOrder.Id) ?.GetViewModel; } @@ -96,6 +112,7 @@ namespace FoodOrdersDatabaseImplement.Implements return context.Orders .Include(x => x.Dish) .Include(x => x.Client) + .Include(x => x.Implementer) .FirstOrDefault(x => x.Id == order.Id) ?.GetViewModel; } diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409151800_5Base.Designer.cs b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409213338_6b.Designer.cs similarity index 82% rename from FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409151800_5Base.Designer.cs rename to FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409213338_6b.Designer.cs index 1900c45..be789c2 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409151800_5Base.Designer.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409213338_6b.Designer.cs @@ -12,8 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace FoodOrdersDatabaseImplement.Migrations { [DbContext(typeof(FoodOrdersDatabase))] - [Migration("20230409151800_5Base")] - partial class _5Base + [Migration("20230409213338_6b")] + partial class _6b { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -116,6 +116,33 @@ namespace FoodOrdersDatabaseImplement.Migrations b.ToTable("DishComponents"); }); + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Qualification") + .HasColumnType("int"); + + b.Property("WorkExperience") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Order", b => { b.Property("Id") @@ -139,6 +166,9 @@ namespace FoodOrdersDatabaseImplement.Migrations b.Property("DishId") .HasColumnType("int"); + b.Property("ImplementerId") + .HasColumnType("int"); + b.Property("Status") .HasColumnType("int"); @@ -151,6 +181,8 @@ namespace FoodOrdersDatabaseImplement.Migrations b.HasIndex("DishId"); + b.HasIndex("ImplementerId"); + b.ToTable("Orders"); }); @@ -187,9 +219,15 @@ namespace FoodOrdersDatabaseImplement.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("FoodOrdersDatabaseImplement.Models.Implementer", "Implementer") + .WithMany("Orders") + .HasForeignKey("ImplementerId"); + b.Navigation("Client"); b.Navigation("Dish"); + + b.Navigation("Implementer"); }); modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Client", b => @@ -208,6 +246,11 @@ namespace FoodOrdersDatabaseImplement.Migrations b.Navigation("Orders"); }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Implementer", b => + { + b.Navigation("Orders"); + }); #pragma warning restore 612, 618 } } diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409151800_5Base.cs b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409213338_6b.cs similarity index 81% rename from FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409151800_5Base.cs rename to FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409213338_6b.cs index 95b54a5..fa28aff 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409151800_5Base.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/20230409213338_6b.cs @@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations; namespace FoodOrdersDatabaseImplement.Migrations { /// - public partial class _5Base : Migration + public partial class _6b : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) @@ -54,6 +54,22 @@ namespace FoodOrdersDatabaseImplement.Migrations table.PrimaryKey("PK_Dishes", x => x.Id); }); + migrationBuilder.CreateTable( + name: "Implementers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ImplementerFIO = table.Column(type: "nvarchar(max)", nullable: false), + Password = table.Column(type: "nvarchar(max)", nullable: false), + WorkExperience = table.Column(type: "int", nullable: false), + Qualification = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Implementers", x => x.Id); + }); + migrationBuilder.CreateTable( name: "DishComponents", columns: table => new @@ -89,6 +105,7 @@ namespace FoodOrdersDatabaseImplement.Migrations .Annotation("SqlServer:Identity", "1, 1"), DishId = table.Column(type: "int", nullable: false), ClientId = table.Column(type: "int", nullable: false), + ImplementerId = table.Column(type: "int", nullable: true), Count = table.Column(type: "int", nullable: false), Sum = table.Column(type: "float", nullable: false), Status = table.Column(type: "int", nullable: false), @@ -110,6 +127,11 @@ namespace FoodOrdersDatabaseImplement.Migrations principalTable: "Dishes", principalColumn: "Id", onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Orders_Implementers_ImplementerId", + column: x => x.ImplementerId, + principalTable: "Implementers", + principalColumn: "Id"); }); migrationBuilder.CreateIndex( @@ -131,6 +153,11 @@ namespace FoodOrdersDatabaseImplement.Migrations name: "IX_Orders_DishId", table: "Orders", column: "DishId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_ImplementerId", + table: "Orders", + column: "ImplementerId"); } /// @@ -150,6 +177,9 @@ namespace FoodOrdersDatabaseImplement.Migrations migrationBuilder.DropTable( name: "Dishes"); + + migrationBuilder.DropTable( + name: "Implementers"); } } } diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/FoodOrdersDatabaseModelSnapshot.cs b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/FoodOrdersDatabaseModelSnapshot.cs index 800b619..fb1f0c2 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/Migrations/FoodOrdersDatabaseModelSnapshot.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/Migrations/FoodOrdersDatabaseModelSnapshot.cs @@ -113,6 +113,33 @@ namespace FoodOrdersDatabaseImplement.Migrations b.ToTable("DishComponents"); }); + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Qualification") + .HasColumnType("int"); + + b.Property("WorkExperience") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Order", b => { b.Property("Id") @@ -136,6 +163,9 @@ namespace FoodOrdersDatabaseImplement.Migrations b.Property("DishId") .HasColumnType("int"); + b.Property("ImplementerId") + .HasColumnType("int"); + b.Property("Status") .HasColumnType("int"); @@ -148,6 +178,8 @@ namespace FoodOrdersDatabaseImplement.Migrations b.HasIndex("DishId"); + b.HasIndex("ImplementerId"); + b.ToTable("Orders"); }); @@ -184,9 +216,15 @@ namespace FoodOrdersDatabaseImplement.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("FoodOrdersDatabaseImplement.Models.Implementer", "Implementer") + .WithMany("Orders") + .HasForeignKey("ImplementerId"); + b.Navigation("Client"); b.Navigation("Dish"); + + b.Navigation("Implementer"); }); modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Client", b => @@ -205,6 +243,11 @@ namespace FoodOrdersDatabaseImplement.Migrations b.Navigation("Orders"); }); + + modelBuilder.Entity("FoodOrdersDatabaseImplement.Models.Implementer", b => + { + b.Navigation("Orders"); + }); #pragma warning restore 612, 618 } } diff --git a/FoodOrders/FoodOrdersDatabaseImplement/Models/Order.cs b/FoodOrders/FoodOrdersDatabaseImplement/Models/Order.cs index fda3459..6edfea4 100644 --- a/FoodOrders/FoodOrdersDatabaseImplement/Models/Order.cs +++ b/FoodOrders/FoodOrdersDatabaseImplement/Models/Order.cs @@ -33,6 +33,8 @@ namespace FoodOrdersDatabaseImplement.Models public virtual Client Client { get; set; } + public Implementer? Implementer { get; private set; } + public DateTime? DateImplement { get; set; } public static Order? Create(OrderBindingModel? model) @@ -73,6 +75,7 @@ namespace FoodOrdersDatabaseImplement.Models ClientId = ClientId, ImplementerId = ImplementerId, ClientFIO = Client.ClientFIO, + ImplementerFIO = Implementer?.ImplementerFIO ?? string.Empty, Count = Count, Sum = Sum, Status = Status, diff --git a/FoodOrders/FoodOrdersFileImplement/Models/Order.cs b/FoodOrders/FoodOrdersFileImplement/Models/Order.cs index 4e512cc..b1f0312 100644 --- a/FoodOrders/FoodOrdersFileImplement/Models/Order.cs +++ b/FoodOrders/FoodOrdersFileImplement/Models/Order.cs @@ -74,6 +74,7 @@ namespace FoodOrdersFileImplement.Models Id = Id, DishId = DishId, ClientId = ClientId, + ImplementerFIO = DataFileSingleton.GetInstance().Implementers.FirstOrDefault(x => x.Id == ImplementerId)?.ImplementerFIO ?? string.Empty, Count = Count, Sum = Sum, Status = Status, diff --git a/FoodOrders/FoodOrdersListImplement/Models/Order.cs b/FoodOrders/FoodOrdersListImplement/Models/Order.cs index 5f1e90c..9f26c67 100644 --- a/FoodOrders/FoodOrdersListImplement/Models/Order.cs +++ b/FoodOrders/FoodOrdersListImplement/Models/Order.cs @@ -52,6 +52,7 @@ namespace FoodOrdersListImplement.Models Id = Id, DishId = DishId, ClientId = ClientId, + ImplementerFIO = DataListSingleton.GetInstance().Implementers.FirstOrDefault(x => x.Id == ImplementerId)?.ImplementerFIO ?? string.Empty, Count = Count, Sum = Sum, Status = Status,