diff --git a/Diner/DinerContracts/BindingModels/ImplementerBindingModel.cs b/Diner/DinerContracts/BindingModels/ImplementerBindingModel.cs new file mode 100644 index 0000000..419bb78 --- /dev/null +++ b/Diner/DinerContracts/BindingModels/ImplementerBindingModel.cs @@ -0,0 +1,20 @@ +using DinerDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerContracts.BindingModels { + public class ImplementerBindingModel : IImplementerModel { + public string ImplementerFIO { get; set; } = string.Empty; + + public string Password { get; set; } = string.Empty; + + public int WorkExperience { get; set; } + + public int Qualification { get; set; } + + public int ID { get; set; } + } +} diff --git a/Diner/DinerContracts/BindingModels/OrderBindingModel.cs b/Diner/DinerContracts/BindingModels/OrderBindingModel.cs index d556b47..f75c1ce 100644 --- a/Diner/DinerContracts/BindingModels/OrderBindingModel.cs +++ b/Diner/DinerContracts/BindingModels/OrderBindingModel.cs @@ -14,6 +14,8 @@ namespace DinerContracts.BindingModels public int ClientID { get; set; } + public int ImplementerID { get; set; } + public int Count { get; set; } public double Sum { get; set; } diff --git a/Diner/DinerContracts/BusinessLogicsContracts/IImplementerLogic.cs b/Diner/DinerContracts/BusinessLogicsContracts/IImplementerLogic.cs new file mode 100644 index 0000000..634788a --- /dev/null +++ b/Diner/DinerContracts/BusinessLogicsContracts/IImplementerLogic.cs @@ -0,0 +1,19 @@ +using DinerContracts.BindingModels; +using DinerContracts.SearchModels; +using DinerContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerContracts.BusinessLogicsContracts { + public interface IImplementerLogic { + List? ReadList(ImplementerSearchModel? model); + ImplementerViewModel? ReadElement(ImplementerSearchModel model); + + bool Create(ImplementerBindingModel model); + bool Update(ImplementerBindingModel model); + bool Delete(ImplementerBindingModel model); + } +} diff --git a/Diner/DinerContracts/BusinessLogicsContracts/IOrderLogic.cs b/Diner/DinerContracts/BusinessLogicsContracts/IOrderLogic.cs index 866aca8..96f829b 100644 --- a/Diner/DinerContracts/BusinessLogicsContracts/IOrderLogic.cs +++ b/Diner/DinerContracts/BusinessLogicsContracts/IOrderLogic.cs @@ -13,10 +13,12 @@ namespace DinerContracts.BusinessLogicsContacts { List? ReadList(OrderSearchModel? model); - bool CreateOrder(OrderBindingModel model); + OrderViewModel? ReadElement(OrderSearchModel model); + + bool CreateOrder(OrderBindingModel model); bool TakeOrderInWork(OrderBindingModel model); bool FinishOrder(OrderBindingModel model); bool DeliveryOrder(OrderBindingModel model); - - } + + } } diff --git a/Diner/DinerContracts/BusinessLogicsContracts/IWorkProcess.cs b/Diner/DinerContracts/BusinessLogicsContracts/IWorkProcess.cs new file mode 100644 index 0000000..a48f80e --- /dev/null +++ b/Diner/DinerContracts/BusinessLogicsContracts/IWorkProcess.cs @@ -0,0 +1,12 @@ +using DinerContracts.BusinessLogicsContacts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerContracts.BusinessLogicsContracts { + public interface IWorkProcess { + void Work(IImplementerLogic implementerLogic, IOrderLogic orderLogic); + } +} diff --git a/Diner/DinerContracts/SearchModels/ImplementerSearchModel.cs b/Diner/DinerContracts/SearchModels/ImplementerSearchModel.cs new file mode 100644 index 0000000..f22ad3e --- /dev/null +++ b/Diner/DinerContracts/SearchModels/ImplementerSearchModel.cs @@ -0,0 +1,20 @@ +using DinerDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerContracts.SearchModels { + public class ImplementerSearchModel { + public string? ImplementerFIO { get; set; } + + public string? Password { get; set; } + + public int? WorkExperience { get; set; } + + public int? Qualification { get; set; } + + public int? ID { get; set; } + } +} diff --git a/Diner/DinerContracts/SearchModels/OrderSearchModel.cs b/Diner/DinerContracts/SearchModels/OrderSearchModel.cs index afb6e2c..6100f4d 100644 --- a/Diner/DinerContracts/SearchModels/OrderSearchModel.cs +++ b/Diner/DinerContracts/SearchModels/OrderSearchModel.cs @@ -1,6 +1,8 @@ -using System; +using DinerDataModels.Enums; +using System; using System.Collections.Generic; using System.Linq; +using System.Numerics; using System.Text; using System.Threading.Tasks; @@ -11,6 +13,8 @@ namespace DinerContracts.SearchModels public int? ID { get; set; } public DateTime? DateFrom { get; set; } public int? ClientID { get; set; } + public int? ImplementerID { get; set; } public DateTime? DateTo { get; set; } + public OrderStatus Status { get; set; } } } diff --git a/Diner/DinerContracts/StoragesContracts/IImplementerStorage.cs b/Diner/DinerContracts/StoragesContracts/IImplementerStorage.cs new file mode 100644 index 0000000..4b68935 --- /dev/null +++ b/Diner/DinerContracts/StoragesContracts/IImplementerStorage.cs @@ -0,0 +1,20 @@ +using DinerContracts.BindingModels; +using DinerContracts.SearchModels; +using DinerContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerContracts.StoragesContracts { + public interface IImplementerStorage { + List GetFullList(); + List GetFilteredList(ImplementerSearchModel model); + + ImplementerViewModel? GetElement(ImplementerSearchModel model); + ImplementerViewModel? Insert(ImplementerBindingModel model); + ImplementerViewModel? Update(ImplementerBindingModel model); + ImplementerViewModel? Delete(ImplementerBindingModel model); + } +} diff --git a/Diner/DinerContracts/ViewModels/ImplementerViewModel.cs b/Diner/DinerContracts/ViewModels/ImplementerViewModel.cs new file mode 100644 index 0000000..e420dfb --- /dev/null +++ b/Diner/DinerContracts/ViewModels/ImplementerViewModel.cs @@ -0,0 +1,26 @@ +using DinerDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerContracts.ViewModels { + public class ImplementerViewModel : IImplementerModel { + + [DisplayName("ФИО исполнителя")] + public string ImplementerFIO { get; set; } = string.Empty; + + [DisplayName("Пароль")] + public string Password { get; set; } = string.Empty; + + [DisplayName("Стаж работы")] + public int WorkExperience { get; set; } + + [DisplayName("Квалификация")] + public int Qualification { get; set; } + + public int ID { get; set; } + } +} diff --git a/Diner/DinerContracts/ViewModels/OrderViewModel.cs b/Diner/DinerContracts/ViewModels/OrderViewModel.cs index 31994ed..1a687b0 100644 --- a/Diner/DinerContracts/ViewModels/OrderViewModel.cs +++ b/Diner/DinerContracts/ViewModels/OrderViewModel.cs @@ -9,17 +9,17 @@ using System.Threading.Tasks; namespace DinerContracts.ViewModels { - public class OrderViewModel : IOrderModel - { + public class OrderViewModel : IOrderModel { public int ClientID { get; set; } public int SnackID { get; set; } + public int ImplementerID { get; set; } [DisplayName("Количество")] public int Count { get; set; } [DisplayName("Сумма")] - public double Sum { get; set; } + public double Sum { get; set; } [DisplayName("Статус")] public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; @@ -39,5 +39,8 @@ namespace DinerContracts.ViewModels [DisplayName("Клиент")] public string ClientFIO { get; set; } = string.Empty; + + [DisplayName("Исполнитель")] + public string ImplementerFIO { get; set; } = string.Empty; } } diff --git a/Diner/DinerDataBaseImplement/DinerDataBase.cs b/Diner/DinerDataBaseImplement/DinerDatabaseBy6Work.cs similarity index 72% rename from Diner/DinerDataBaseImplement/DinerDataBase.cs rename to Diner/DinerDataBaseImplement/DinerDatabaseBy6Work.cs index d9dd3ba..ebab4e9 100644 --- a/Diner/DinerDataBaseImplement/DinerDataBase.cs +++ b/Diner/DinerDataBaseImplement/DinerDatabaseBy6Work.cs @@ -3,11 +3,11 @@ using Microsoft.EntityFrameworkCore; namespace DinerDataBaseImplement { - public class DinerDataBase : DbContext + public class DinerDatabaseBy6Work : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (optionsBuilder.IsConfigured == false) { - optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-O0N00SH\SQLEXPRESS;Initial Catalog=DinerDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-O0N00SH\SQLEXPRESS;Initial Catalog=DinerDatabaseBy6Work;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); } base.OnConfiguring(optionsBuilder); } @@ -16,5 +16,6 @@ namespace DinerDataBaseImplement public virtual DbSet ProductComponents { get; set; } public virtual DbSet Orders { get; set; } public virtual DbSet Clients { get; set; } + public virtual DbSet Implementers { get; set; } } } \ No newline at end of file diff --git a/Diner/DinerDataBaseImplement/Implements/ClientStorage.cs b/Diner/DinerDataBaseImplement/Implements/ClientStorage.cs index 39b2a25..c1d9cb2 100644 --- a/Diner/DinerDataBaseImplement/Implements/ClientStorage.cs +++ b/Diner/DinerDataBaseImplement/Implements/ClientStorage.cs @@ -18,7 +18,7 @@ namespace DinerDataBaseImplement.Implements { if (newClient == null) { return null; } - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); context.Clients.Add(newClient); context.SaveChanges(); @@ -29,7 +29,7 @@ namespace DinerDataBaseImplement.Implements { } public ClientViewModel? Update(ClientBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); var client = context.Clients.FirstOrDefault(x => x.ID == model.ID); if (client == null) { return null; @@ -40,7 +40,7 @@ namespace DinerDataBaseImplement.Implements { } public ClientViewModel? Delete(ClientBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); var element = context.Clients.FirstOrDefault(x => x.ID == model.ID); if (element != null) { context.Clients.Remove(element); @@ -51,7 +51,7 @@ namespace DinerDataBaseImplement.Implements { } public ClientViewModel? GetElement(ClientSearchModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); if (model.ID.HasValue) { return context.Clients .Include(x => x.Orders) @@ -71,7 +71,7 @@ namespace DinerDataBaseImplement.Implements { if (string.IsNullOrEmpty(model.ClientFIO)) { return new(); } - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); return context.Clients .Include(x => x.Orders) @@ -81,7 +81,7 @@ namespace DinerDataBaseImplement.Implements { } public List GetFullList() { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); return context.Clients .Include(x => x.Orders) diff --git a/Diner/DinerDataBaseImplement/Implements/FoodStorage.cs b/Diner/DinerDataBaseImplement/Implements/FoodStorage.cs index 44d0bbc..df26f66 100644 --- a/Diner/DinerDataBaseImplement/Implements/FoodStorage.cs +++ b/Diner/DinerDataBaseImplement/Implements/FoodStorage.cs @@ -16,7 +16,7 @@ namespace DinerDataBaseImplement.Implements { public FoodViewModel? Delete(FoodBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); var element = context.Components.FirstOrDefault(x => x.ID == model.ID); if (element != null) { @@ -32,7 +32,7 @@ namespace DinerDataBaseImplement.Implements if (string.IsNullOrEmpty(model.ComponentName) && !model.ID.HasValue) { return null; } - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); return context.Components .FirstOrDefault(x => (!string.IsNullOrEmpty(model.ComponentName) && x.ComponentName == model.ComponentName) || model.ID.HasValue && @@ -45,7 +45,7 @@ namespace DinerDataBaseImplement.Implements return new(); } - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); return context.Components.Where(x => x.ComponentName.Contains(model.ComponentName)) .Select(x => x.GetViewModel).ToList(); @@ -53,7 +53,7 @@ namespace DinerDataBaseImplement.Implements public List GetFullList() { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); return context.Components.Select(x => x.GetViewModel).ToList(); } @@ -63,7 +63,7 @@ namespace DinerDataBaseImplement.Implements if (newComponent == null) { return null; } - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); context.Components.Add(newComponent); context.SaveChanges(); return newComponent.GetViewModel; @@ -71,7 +71,7 @@ namespace DinerDataBaseImplement.Implements public FoodViewModel? Update(FoodBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); var component = context.Components.FirstOrDefault(x => x.ID == model.ID); if (component == null) { return null; diff --git a/Diner/DinerDataBaseImplement/Implements/ImplementerStorage.cs b/Diner/DinerDataBaseImplement/Implements/ImplementerStorage.cs new file mode 100644 index 0000000..8ec23a4 --- /dev/null +++ b/Diner/DinerDataBaseImplement/Implements/ImplementerStorage.cs @@ -0,0 +1,89 @@ +using DinerContracts.BindingModels; +using DinerContracts.SearchModels; +using DinerContracts.StoragesContracts; +using DinerContracts.ViewModels; +using DinerDataBaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; + +namespace DinerDataBaseImplement.Implements { + public class ImplementerStorage : IImplementerStorage { + + public ImplementerViewModel? Insert(ImplementerBindingModel model) { + var newImplementer = Implementer.Create(model); + if (newImplementer == null) { + return null; + } + using var context = new DinerDatabaseBy6Work(); + context.Implementers.Add(newImplementer); + context.SaveChanges(); + + return context.Implementers + .Include(x => x.Orders) + .FirstOrDefault(x => x.ID == newImplementer.ID) + ?.GetViewModel; + } + + public ImplementerViewModel? Update(ImplementerBindingModel model) { + using var context = new DinerDatabaseBy6Work(); + var implementer = context.Implementers.FirstOrDefault(x => x.ID == model.ID); + if (implementer == null) { + return null; + } + implementer.Update(model); + context.SaveChanges(); + return implementer.GetViewModel; + } + + public ImplementerViewModel? Delete(ImplementerBindingModel model) { + using var context = new DinerDatabaseBy6Work(); + var element = context.Implementers.FirstOrDefault(x => x.ID == model.ID); + if (element != null) { + context.Implementers.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + public ImplementerViewModel? GetElement(ImplementerSearchModel model) { + using var context = new DinerDatabaseBy6Work(); + if (model.ID.HasValue) { + return context.Implementers + .Include(x => x.Orders) + .FirstOrDefault(x => model.ID.HasValue && x.ID == model.ID) + ?.GetViewModel; + } + return new(); + } + + public List GetFilteredList(ImplementerSearchModel model) { + if (string.IsNullOrEmpty(model.ImplementerFIO)) { + return new(); + } + using var context = new DinerDatabaseBy6Work(); + + return context.Implementers + .Include(x => x.Orders) + .Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFullList() { + using var context = new DinerDatabaseBy6Work(); + + return context.Implementers + .Include(x => x.Orders) + .Select(x => x.GetViewModel) + .ToList(); + } + + + } +} diff --git a/Diner/DinerDataBaseImplement/Implements/OrderStorage.cs b/Diner/DinerDataBaseImplement/Implements/OrderStorage.cs index 06008cd..1379804 100644 --- a/Diner/DinerDataBaseImplement/Implements/OrderStorage.cs +++ b/Diner/DinerDataBaseImplement/Implements/OrderStorage.cs @@ -16,7 +16,7 @@ namespace DinerDataBaseImplement.Implements { public OrderViewModel? Delete(OrderBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); var element = context.Orders.FirstOrDefault(x => x.ID == model.ID); if (element != null) { @@ -32,21 +32,23 @@ namespace DinerDataBaseImplement.Implements if (!model.ID.HasValue) { return null; } - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); return context.Orders .Include(x => x.Snack) .Include(x => x.Client) + .Include(x => x.Implementer) .FirstOrDefault(x => model.ID.HasValue && x.ID == model.ID) ?.GetViewModel; } public List GetFilteredList(OrderSearchModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); if (!model.ID.HasValue && model.DateFrom.HasValue && model.DateTo.HasValue) { return context.Orders .Include(x => x.Snack) .Include(x => x.Client) + .Include(x => x.Implementer) .Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) .Select(x => x.GetViewModel) .ToList(); @@ -55,6 +57,7 @@ namespace DinerDataBaseImplement.Implements return context.Orders .Include(x => x.Snack) .Include(x => x.Client) + .Include(x => x.Implementer) .Where(x => x.ID == model.ID) .Select(x => x.GetViewModel) .ToList(); @@ -63,6 +66,7 @@ namespace DinerDataBaseImplement.Implements return context.Orders .Include(x => x.Snack) .Include(x => x.Client) + .Include(x => x.Implementer) .Where(x => x.ClientID == model.ClientID) .Select(x => x.GetViewModel) .ToList(); @@ -72,12 +76,13 @@ namespace DinerDataBaseImplement.Implements public List GetFullList() { - using var context = new DinerDataBase(); - return context.Orders.Include(x => x.Snack).Include(x => x.Client).Select(x => x.GetViewModel).ToList(); + using var context = new DinerDatabaseBy6Work(); + return context.Orders.Include(x => x.Snack).Include(x => x.Client).Include(x => x.Implementer) + .Select(x => x.GetViewModel).ToList(); } public OrderViewModel? Insert(OrderBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); var newOrder = Order.Create(model); if (newOrder == null) { return null; @@ -86,10 +91,11 @@ namespace DinerDataBaseImplement.Implements context.SaveChanges(); return context.Orders.Include(x => x.Snack) .Include(x => x.Client) + .Include(x => x.Implementer) .FirstOrDefault(x => x.ID == newOrder.ID)?.GetViewModel; } public OrderViewModel? Update(OrderBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); var order = context.Orders.FirstOrDefault(x => x.ID == model.ID); if (order == null) { return null; } order.Update(model); @@ -97,6 +103,7 @@ namespace DinerDataBaseImplement.Implements return context.Orders .Include(x => x.Snack) .Include(x => x.Client) + .Include(x => x.Implementer) .FirstOrDefault(x => x.ID == model.ID)? .GetViewModel; } diff --git a/Diner/DinerDataBaseImplement/Implements/SnackStorage.cs b/Diner/DinerDataBaseImplement/Implements/SnackStorage.cs index 85390bc..605e770 100644 --- a/Diner/DinerDataBaseImplement/Implements/SnackStorage.cs +++ b/Diner/DinerDataBaseImplement/Implements/SnackStorage.cs @@ -17,7 +17,7 @@ namespace DinerDataBaseImplement.Implements { public SnackViewModel? Delete(SnackBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); var element = context.Snacks .Include(x => x.Components) .Include(x => x.Orders) @@ -36,7 +36,7 @@ namespace DinerDataBaseImplement.Implements if (string.IsNullOrEmpty(model.ProductName) && !model.ID.HasValue) { return null; } - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); return context.Snacks .Include(x => x.Components) .ThenInclude(x => x.Component) @@ -50,7 +50,7 @@ namespace DinerDataBaseImplement.Implements if (string.IsNullOrEmpty(model.ProductName)) { return new(); } - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); return context.Snacks .Include(x => x.Components) .ThenInclude(x => x.Component) @@ -61,7 +61,7 @@ namespace DinerDataBaseImplement.Implements public List GetFullList() { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); return context.Snacks .Include(x => x.Components) .ThenInclude(x => x.Component).ToList() @@ -70,7 +70,7 @@ namespace DinerDataBaseImplement.Implements public SnackViewModel? Insert(SnackBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); var newProduct = Snack.Create(context, model); if (newProduct == null) { return null; @@ -82,7 +82,7 @@ namespace DinerDataBaseImplement.Implements public SnackViewModel? Update(SnackBindingModel model) { - using var context = new DinerDataBase(); + using var context = new DinerDatabaseBy6Work(); using var transcation = context.Database.BeginTransaction(); try { diff --git a/Diner/DinerDataBaseImplement/Migrations/20240511111831_InitMigration.Designer.cs b/Diner/DinerDataBaseImplement/Migrations/20240513124832_InitMigration.Designer.cs similarity index 80% rename from Diner/DinerDataBaseImplement/Migrations/20240511111831_InitMigration.Designer.cs rename to Diner/DinerDataBaseImplement/Migrations/20240513124832_InitMigration.Designer.cs index 079f0bc..1af3e52 100644 --- a/Diner/DinerDataBaseImplement/Migrations/20240511111831_InitMigration.Designer.cs +++ b/Diner/DinerDataBaseImplement/Migrations/20240513124832_InitMigration.Designer.cs @@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace DinerDataBaseImplement.Migrations { - [DbContext(typeof(DinerDataBase))] - [Migration("20240511111831_InitMigration")] + [DbContext(typeof(DinerDatabaseBy6Work))] + [Migration("20240513124832_InitMigration")] partial class InitMigration { /// @@ -70,6 +70,33 @@ namespace DinerDataBaseImplement.Migrations b.ToTable("Components"); }); + modelBuilder.Entity("DinerDataBaseImplement.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("DinerDataBaseImplement.Models.Order", b => { b.Property("ID") @@ -90,6 +117,9 @@ namespace DinerDataBaseImplement.Migrations b.Property("DateImplement") .HasColumnType("datetime2"); + b.Property("ImplementerID") + .HasColumnType("int"); + b.Property("SnackID") .HasColumnType("int"); @@ -103,6 +133,8 @@ namespace DinerDataBaseImplement.Migrations b.HasIndex("ClientID"); + b.HasIndex("ImplementerID"); + b.HasIndex("SnackID"); b.ToTable("Orders"); @@ -162,6 +194,12 @@ namespace DinerDataBaseImplement.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("DinerDataBaseImplement.Models.Implementer", "Implementer") + .WithMany("Orders") + .HasForeignKey("ImplementerID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + b.HasOne("DinerDataBaseImplement.Models.Snack", "Snack") .WithMany("Orders") .HasForeignKey("SnackID") @@ -170,6 +208,8 @@ namespace DinerDataBaseImplement.Migrations b.Navigation("Client"); + b.Navigation("Implementer"); + b.Navigation("Snack"); }); @@ -202,6 +242,11 @@ namespace DinerDataBaseImplement.Migrations b.Navigation("SnackFood"); }); + modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b => + { + b.Navigation("Orders"); + }); + modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b => { b.Navigation("Components"); diff --git a/Diner/DinerDataBaseImplement/Migrations/20240511111831_InitMigration.cs b/Diner/DinerDataBaseImplement/Migrations/20240513124832_InitMigration.cs similarity index 81% rename from Diner/DinerDataBaseImplement/Migrations/20240511111831_InitMigration.cs rename to Diner/DinerDataBaseImplement/Migrations/20240513124832_InitMigration.cs index d1af37c..fb50314 100644 --- a/Diner/DinerDataBaseImplement/Migrations/20240511111831_InitMigration.cs +++ b/Diner/DinerDataBaseImplement/Migrations/20240513124832_InitMigration.cs @@ -40,6 +40,22 @@ namespace DinerDataBaseImplement.Migrations table.PrimaryKey("PK_Components", 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: "Snacks", columns: table => new @@ -62,6 +78,7 @@ namespace DinerDataBaseImplement.Migrations .Annotation("SqlServer:Identity", "1, 1"), SnackID = table.Column(type: "int", nullable: false), ClientID = table.Column(type: "int", nullable: false), + ImplementerID = table.Column(type: "int", nullable: false), Count = table.Column(type: "int", nullable: false), Sum = table.Column(type: "float", nullable: false), Status = table.Column(type: "int", nullable: false), @@ -77,6 +94,12 @@ namespace DinerDataBaseImplement.Migrations principalTable: "Clients", principalColumn: "ID", onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Orders_Implementers_ImplementerID", + column: x => x.ImplementerID, + principalTable: "Implementers", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "FK_Orders_Snacks_SnackID", column: x => x.SnackID, @@ -117,6 +140,11 @@ namespace DinerDataBaseImplement.Migrations table: "Orders", column: "ClientID"); + migrationBuilder.CreateIndex( + name: "IX_Orders_ImplementerID", + table: "Orders", + column: "ImplementerID"); + migrationBuilder.CreateIndex( name: "IX_Orders_SnackID", table: "Orders", @@ -145,6 +173,9 @@ namespace DinerDataBaseImplement.Migrations migrationBuilder.DropTable( name: "Clients"); + migrationBuilder.DropTable( + name: "Implementers"); + migrationBuilder.DropTable( name: "Components"); diff --git a/Diner/DinerDataBaseImplement/Migrations/DinerDataBaseModelSnapshot.cs b/Diner/DinerDataBaseImplement/Migrations/DinerDatabaseBy6WorkModelSnapshot.cs similarity index 80% rename from Diner/DinerDataBaseImplement/Migrations/DinerDataBaseModelSnapshot.cs rename to Diner/DinerDataBaseImplement/Migrations/DinerDatabaseBy6WorkModelSnapshot.cs index 57ee7ab..e348e00 100644 --- a/Diner/DinerDataBaseImplement/Migrations/DinerDataBaseModelSnapshot.cs +++ b/Diner/DinerDataBaseImplement/Migrations/DinerDatabaseBy6WorkModelSnapshot.cs @@ -10,8 +10,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace DinerDataBaseImplement.Migrations { - [DbContext(typeof(DinerDataBase))] - partial class DinerDataBaseModelSnapshot : ModelSnapshot + [DbContext(typeof(DinerDatabaseBy6Work))] + partial class DinerDatabaseBy6WorkModelSnapshot : ModelSnapshot { protected override void BuildModel(ModelBuilder modelBuilder) { @@ -67,6 +67,33 @@ namespace DinerDataBaseImplement.Migrations b.ToTable("Components"); }); + modelBuilder.Entity("DinerDataBaseImplement.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("DinerDataBaseImplement.Models.Order", b => { b.Property("ID") @@ -87,6 +114,9 @@ namespace DinerDataBaseImplement.Migrations b.Property("DateImplement") .HasColumnType("datetime2"); + b.Property("ImplementerID") + .HasColumnType("int"); + b.Property("SnackID") .HasColumnType("int"); @@ -100,6 +130,8 @@ namespace DinerDataBaseImplement.Migrations b.HasIndex("ClientID"); + b.HasIndex("ImplementerID"); + b.HasIndex("SnackID"); b.ToTable("Orders"); @@ -159,6 +191,12 @@ namespace DinerDataBaseImplement.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("DinerDataBaseImplement.Models.Implementer", "Implementer") + .WithMany("Orders") + .HasForeignKey("ImplementerID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + b.HasOne("DinerDataBaseImplement.Models.Snack", "Snack") .WithMany("Orders") .HasForeignKey("SnackID") @@ -167,6 +205,8 @@ namespace DinerDataBaseImplement.Migrations b.Navigation("Client"); + b.Navigation("Implementer"); + b.Navigation("Snack"); }); @@ -199,6 +239,11 @@ namespace DinerDataBaseImplement.Migrations b.Navigation("SnackFood"); }); + modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b => + { + b.Navigation("Orders"); + }); + modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b => { b.Navigation("Components"); diff --git a/Diner/DinerDataBaseImplement/Models/Implementer.cs b/Diner/DinerDataBaseImplement/Models/Implementer.cs new file mode 100644 index 0000000..aa051da --- /dev/null +++ b/Diner/DinerDataBaseImplement/Models/Implementer.cs @@ -0,0 +1,72 @@ +using DinerContracts.BindingModels; +using DinerContracts.ViewModels; +using DinerDataModels.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 DinerDataBaseImplement.Models { + public class Implementer : IImplementerModel { + + [Required] + public string ImplementerFIO { get; set; } = string.Empty; + + [Required] + public string Password { get; set; } = string.Empty; + + [Required] + public int WorkExperience { get; set; } + + [Required] + public int Qualification { get; set; } + + public int ID { get; set; } + + [ForeignKey("ImplementerID")] + public virtual List Orders { get; set; } = new(); + + public static Implementer? Create(ImplementerBindingModel? model) { + if (model == null) { + return null; + } + return new Implementer() { + ImplementerFIO = model.ImplementerFIO, + Password = model.Password, + WorkExperience = model.WorkExperience, + Qualification = model.Qualification, + ID = model.ID + }; + } + + public static Implementer Create(ImplementerViewModel model) { + return new Implementer() { + ImplementerFIO = model.ImplementerFIO, + Password = model.Password, + WorkExperience = model.WorkExperience, + Qualification = model.Qualification, + ID = model.ID + }; + } + + public void Update(ImplementerBindingModel? model) { + if (model == null) { + return; + } + ImplementerFIO = model.ImplementerFIO; + Password = model.Password; + Qualification = model.Qualification; + } + + public ImplementerViewModel GetViewModel => new() { + ImplementerFIO = ImplementerFIO, + Password = Password, + WorkExperience = WorkExperience, + Qualification = Qualification, + ID = ID + }; + } +} diff --git a/Diner/DinerDataBaseImplement/Models/Order.cs b/Diner/DinerDataBaseImplement/Models/Order.cs index b4b7f56..5bf9208 100644 --- a/Diner/DinerDataBaseImplement/Models/Order.cs +++ b/Diner/DinerDataBaseImplement/Models/Order.cs @@ -16,6 +16,8 @@ namespace DinerDataBaseImplement.Models [Required] public int ClientID { get; set; } + [Required] + public int ImplementerID { get; set; } [Required] public int Count { get; set; } @@ -34,6 +36,7 @@ namespace DinerDataBaseImplement.Models public virtual Snack Snack { get; set; } public virtual Client Client { get; set; } + public virtual Implementer Implementer { get; set; } public static Order? Create(OrderBindingModel? model) { @@ -47,7 +50,8 @@ namespace DinerDataBaseImplement.Models Status = model.Status, DateCreate = model.DateCreate, DateImplement = model.DateImplement, - ClientID = model.ClientID + ClientID = model.ClientID, + ImplementerID = model.ImplementerID }; } public void Update(OrderBindingModel? model) @@ -68,8 +72,9 @@ namespace DinerDataBaseImplement.Models DateImplement = DateImplement, ProductName = Snack.ProductName, ClientID = ClientID, - ClientFIO = Client.ClientFIO + ClientFIO = Client.ClientFIO, + ImplementerID = ImplementerID, + ImplementerFIO = Implementer.ImplementerFIO }; - } } diff --git a/Diner/DinerDataBaseImplement/Models/Snack.cs b/Diner/DinerDataBaseImplement/Models/Snack.cs index 484e738..74666b5 100644 --- a/Diner/DinerDataBaseImplement/Models/Snack.cs +++ b/Diner/DinerDataBaseImplement/Models/Snack.cs @@ -44,7 +44,7 @@ namespace DinerDataBaseImplement.Models [ForeignKey("SnackID")] public virtual List Orders { get; set; } = new(); - public static Snack? Create(DinerDataBase context,SnackBindingModel model) + public static Snack? Create(DinerDatabaseBy6Work context,SnackBindingModel model) { return new Snack() { @@ -72,7 +72,7 @@ namespace DinerDataBaseImplement.Models ProductComponents = ProductComponents }; - public void UpdateComponents(DinerDataBase context, SnackBindingModel model) { + public void UpdateComponents(DinerDatabaseBy6Work context, SnackBindingModel model) { var productComponents = context.ProductComponents.Where(rec => rec.SnackID == model.ID).ToList(); if (ProductComponents != null && ProductComponents.Count > 0) { context.ProductComponents.RemoveRange(productComponents.Where(rec => !model.ProductComponents.ContainsKey(rec.ComponentID))); diff --git a/Diner/DinerDataModels/Models/IImplementerModel.cs b/Diner/DinerDataModels/Models/IImplementerModel.cs new file mode 100644 index 0000000..fc13188 --- /dev/null +++ b/Diner/DinerDataModels/Models/IImplementerModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerDataModels.Models { + public interface IImplementerModel : IID { + string ImplementerFIO { get; } + string Password { get; } + int WorkExperience { get; } + int Qualification { get; } + } +} diff --git a/Diner/DinerListImplement/DataListSingleton.cs b/Diner/DinerListImplement/DataListSingleton.cs index 37ff0c8..e6819c5 100644 --- a/Diner/DinerListImplement/DataListSingleton.cs +++ b/Diner/DinerListImplement/DataListSingleton.cs @@ -15,12 +15,14 @@ namespace DinerListImplement public List Snacks { get; set; } public List Orders { get; set; } public List Clients { get; set; } + public List Implementers { get; set; } private DataListSingleton() { Foods = new List(); Snacks = new List(); Orders = new List(); Clients = new List(); + Implementers = new List(); } public static DataListSingleton GetInstance() { if (_instance == null) _instance = new DataListSingleton(); diff --git a/Diner/DinerListImplement/Implements/ClientStorage.cs b/Diner/DinerListImplement/Implements/ClientStorage.cs index 5b96ff5..7d41eca 100644 --- a/Diner/DinerListImplement/Implements/ClientStorage.cs +++ b/Diner/DinerListImplement/Implements/ClientStorage.cs @@ -22,7 +22,7 @@ namespace DinerListImplement.Implements { model.ID = 1; foreach (var client in _source.Clients) { if (model.ID <= client.ID) { - model.ID = client.ID; + model.ID = client.ID + 1; } } var newClient = Client.Create(model); diff --git a/Diner/DinerListImplement/Implements/ImplementerStorage.cs b/Diner/DinerListImplement/Implements/ImplementerStorage.cs new file mode 100644 index 0000000..e425706 --- /dev/null +++ b/Diner/DinerListImplement/Implements/ImplementerStorage.cs @@ -0,0 +1,95 @@ +using DinerContracts.BindingModels; +using DinerContracts.BusinessLogicsContracts; +using DinerContracts.SearchModels; +using DinerContracts.StoragesContracts; +using DinerContracts.ViewModels; +using DinerListImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerListImplement.Implements { + public class ImplementerStorage : IImplementerStorage { + + private readonly DataListSingleton _source; + + public ImplementerStorage() { + _source = DataListSingleton.GetInstance(); + } + + public ImplementerViewModel? Insert(ImplementerBindingModel model) { + model.ID = 1; + foreach (var implementer in _source.Implementers) { + if (model.ID <= implementer.ID) { + model.ID = implementer.ID + 1; + } + } + var newImplementer = Implementer.Create(model); + if (newImplementer == null) { + return null; + } + _source.Implementers.Add(newImplementer); + return newImplementer.GetViewModel; + } + + public ImplementerViewModel? Update(ImplementerBindingModel model) { + foreach (var implementer in _source.Implementers) { + if (implementer.ID == model.ID) { + implementer.Update(model); + return implementer.GetViewModel; + } + } + return null; + } + + public ImplementerViewModel? Delete(ImplementerBindingModel model) { + for (int i = 0; i < _source.Implementers.Count; ++i) { + if (_source.Implementers[i].ID == model.ID) { + var element = _source.Implementers[i]; + _source.Implementers.RemoveAt(i); + return element.GetViewModel; + } + } + return null; + } + + public ImplementerViewModel? GetElement(ImplementerSearchModel model) { + if (string.IsNullOrEmpty(model.ImplementerFIO) && !model.ID.HasValue) { + return null; + } + foreach (var implementer in _source.Implementers) { + if ((!string.IsNullOrEmpty(model.ImplementerFIO) && + implementer.ImplementerFIO == model.ImplementerFIO) || + (model.ID.HasValue && implementer.ID == model.ID)) { + return implementer.GetViewModel; + } + } + return null; + } + + public List GetFilteredList(ImplementerSearchModel model) { + var result = new List(); + if (string.IsNullOrEmpty(model.ImplementerFIO)) { + return result; + } + foreach (var implementer in _source.Implementers) { + if (implementer.ImplementerFIO.Contains(model.ImplementerFIO)) { + result.Add(implementer.GetViewModel); + } + } + return result; + } + + public List GetFullList() { + var result = new List(); + foreach (var implementer in _source.Implementers) { + result.Add(implementer.GetViewModel); + } + return result; + } + + + } +} diff --git a/Diner/DinerListImplement/Models/Implementer.cs b/Diner/DinerListImplement/Models/Implementer.cs new file mode 100644 index 0000000..149fece --- /dev/null +++ b/Diner/DinerListImplement/Models/Implementer.cs @@ -0,0 +1,50 @@ +using DinerContracts.BindingModels; +using DinerContracts.ViewModels; +using DinerDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerListImplement.Models { + public class Implementer : IImplementerModel { + public string ImplementerFIO { get; private set; } = string.Empty; + + public string Password { get; private set; } = string.Empty; + + public int WorkExperience { get; private set; } + + public int Qualification { get; private set; } + + public int ID { get; set; } + + public static Implementer? Create(ImplementerBindingModel? model) { + if (model == null) { + return null; + } + return new Implementer() { + ImplementerFIO = model.ImplementerFIO, + Password = model.Password, + WorkExperience = model.WorkExperience, + Qualification = model.Qualification, + }; + } + public void Update(ImplementerBindingModel? model) { + if (model == null) { + return; + } + ImplementerFIO = model.ImplementerFIO; + Password = model.Password; + Qualification = model.Qualification; + } + + public ImplementerViewModel GetViewModel => new() { + ImplementerFIO = ImplementerFIO, + Password = Password, + WorkExperience = WorkExperience, + Qualification = Qualification, + ID = ID + }; + } +} diff --git a/Diner/DinerListImplement/Models/Order.cs b/Diner/DinerListImplement/Models/Order.cs index 41ce708..c6987fe 100644 --- a/Diner/DinerListImplement/Models/Order.cs +++ b/Diner/DinerListImplement/Models/Order.cs @@ -14,6 +14,10 @@ namespace DinerListImplement.Models { public int SnackID { get; private set; } + public int ClientID { get; private set; } + + public int ImplementerID { get; private set; } + public int Count { get; set; } public double Sum { get; private set; } @@ -26,6 +30,12 @@ namespace DinerListImplement.Models public int ID { get; private set; } + public string? ProductName { get; private set; } + + public string? ClientFIO { get; private set; } + + public string? ImplementerFIO { get; private set; } + public static Order? Create(OrderBindingModel? model) { if (model == null) return null; return new Order() @@ -37,6 +47,8 @@ namespace DinerListImplement.Models Status = model.Status, DateCreate = model.DateCreate, DateImplement = model.DateImplement, + ClientID = model.ClientID, + ImplementerID = model.ImplementerID, }; } public void Update(OrderBindingModel? model) { @@ -52,7 +64,12 @@ namespace DinerListImplement.Models Sum = Sum, Status = Status, DateCreate = DateCreate, - DateImplement = DateImplement + DateImplement = DateImplement, + ClientID = ClientID, + ImplementerID = ImplementerID, + ProductName = ProductName, + ClientFIO = ClientFIO, + ImplementerFIO = ImplementerFIO }; } } diff --git a/Diner/DinerRestAPI/Program.cs b/Diner/DinerRestAPI/Program.cs index eb7762b..c01ec09 100644 --- a/Diner/DinerRestAPI/Program.cs +++ b/Diner/DinerRestAPI/Program.cs @@ -4,6 +4,7 @@ using DinerContracts.BusinessLogicsContracts; using DinerContracts.StoragesContracts; using DinerDataBaseImplement.Implements; using DineryBusinessLogic.BusinessLogic; +using DocumentFormat.OpenXml.VariantTypes; using Microsoft.OpenApi.Models; namespace DinerRestAPI { @@ -17,10 +18,12 @@ namespace DinerRestAPI { builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); + builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); + builder.Services.AddTransient(); // Add services to the container. diff --git a/Diner/DinerRestApi/Controllers/ImplementerController.cs b/Diner/DinerRestApi/Controllers/ImplementerController.cs new file mode 100644 index 0000000..25fe1e3 --- /dev/null +++ b/Diner/DinerRestApi/Controllers/ImplementerController.cs @@ -0,0 +1,89 @@ +using DinerContracts.BindingModels; +using DinerContracts.BusinessLogicsContacts; +using DinerContracts.BusinessLogicsContracts; +using DinerContracts.SearchModels; +using DinerContracts.ViewModels; +using DinerDataModels.Enums; +using DocumentFormat.OpenXml.Office2010.PowerPoint; +using Microsoft.AspNetCore.Mvc; + +namespace DinerRestApi.Controllers { + + [Route("api/[controller]/[action]")] + [ApiController] + + public class ImplementerController : Controller { + + private readonly ILogger _logger; + private readonly IOrderLogic _order; + private readonly IImplementerLogic _logic; + + public ImplementerController(ILogger logger, IOrderLogic order, IImplementerLogic implementerLogic) { + _logger = logger; + _order = order; + _logic = implementerLogic; + } + + [HttpGet] + public ImplementerViewModel? Login(string login, string password) { + try { + return _logic.ReadElement(new ImplementerSearchModel { + ImplementerFIO = login, + Password = password + }); + } + catch (Exception ex) { + _logger.LogError(ex, "Ошибка авторизации сотрудников"); + throw; + } + } + + [HttpGet] + public List? GetNewOrderss() { + try { + return _order.ReadList(new OrderSearchModel { + Status = OrderStatus.Принят + }); + } + catch (Exception ex) { + _logger.LogError(ex, "Ошибка получения новых заказов"); + throw; + } + } + + [HttpGet] + public OrderViewModel? GetImplementerOrder(int implementerID) { + try { + return _order.ReadElement(new OrderSearchModel { + ImplementerID = implementerID + }); + } + catch (Exception ex) { + _logger.LogError(ex, "Ошибка получения текущего заказа исполнителя"); + throw; + } + } + + [HttpPost] + public void TakeOrderInWork(OrderBindingModel model) { + try { + _order.TakeOrderInWork(model); + } + catch (Exception ex) { + _logger.LogError(ex, $"Ошибка перевода заказа с №{model.ID} в работу"); + throw; + } + } + + [HttpPost] + public void FinishOrder(OrderBindingModel model) { + try { + _order.FinishOrder(model); + } + catch (Exception ex) { + _logger.LogError(ex, $"Ошибка отметки о готовности заказа с №{model.ID}"); + throw; + } + } + } +} diff --git a/Diner/DinerShopImplement/DataFileSingleton.cs b/Diner/DinerShopImplement/DataFileSingleton.cs index eb85557..5d51c21 100644 --- a/Diner/DinerShopImplement/DataFileSingleton.cs +++ b/Diner/DinerShopImplement/DataFileSingleton.cs @@ -20,16 +20,20 @@ namespace DinerFileImplement private readonly string ClientFileName = "Client.xml"; + private readonly string ImplementerFileName = "Implementer.xml"; + public List Foods { get; set; } public List Orders { get; private set; } public List Snacks { get; private set; } public List Clients { get; private set; } + public List Implementers { get; private set; } private DataFileSingleton() { Foods = LoadData(FoodFileName, "Food", x => Food.Create(x)!)!; Snacks = LoadData(SnackFileName, "Snack", x => Snack.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!; + Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!; } public static DataFileSingleton GetInstance() { if (instance == null) instance = new DataFileSingleton(); @@ -42,7 +46,9 @@ namespace DinerFileImplement public void SaveOrder() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); public void SaveClient() => SaveData(Clients, ClientFileName, "Clients", - x => x.GetXElement); + x => x.GetXElement); + public void SaveImplementer() => SaveData(Implementers, ImplementerFileName, "Implementers", + x => x.GetXElement); private static void SaveData(List data, string filename, string xmlNodeName, Func selectFunction) diff --git a/Diner/DinerShopImplement/Implements/ImplementerStorage.cs b/Diner/DinerShopImplement/Implements/ImplementerStorage.cs new file mode 100644 index 0000000..fc30d04 --- /dev/null +++ b/Diner/DinerShopImplement/Implements/ImplementerStorage.cs @@ -0,0 +1,75 @@ +using DinerContracts.BindingModels; +using DinerContracts.SearchModels; +using DinerContracts.StoragesContracts; +using DinerContracts.ViewModels; +using DinerFileImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DinerFileImplement.Implements { + public class ImplementerStorage : IImplementerStorage { + + private readonly DataFileSingleton _source; + + private ImplementerStorage() { + _source = DataFileSingleton.GetInstance(); + } + + public ImplementerViewModel? Insert(ImplementerBindingModel model) { + model.ID = _source.Implementers.Count > 0 ? _source.Implementers.Max(x => x.ID) + 1 : 1; + var newImplementer = Implementer.Create(model); + if (newImplementer == null) { + return null; + } + _source.Implementers.Add(newImplementer); + _source.SaveImplementer(); + return newImplementer.GetViewModel; + } + + public ImplementerViewModel? Update(ImplementerBindingModel model) { + var implementer = _source.Implementers.FirstOrDefault(x => x.ID == model.ID); + if (implementer == null) { + return null; + } + implementer.Update(model); + _source.SaveImplementer(); + return implementer.GetViewModel; + } + + public ImplementerViewModel? Delete(ImplementerBindingModel model) { + var element = _source.Implementers.FirstOrDefault(x => x.ID == model.ID); + if ( element != null) { + _source.Implementers.Remove(element); + _source.SaveImplementer(); + return element.GetViewModel; + } + return null; + } + + public ImplementerViewModel? GetElement(ImplementerSearchModel model) { + if (string.IsNullOrEmpty(model.ImplementerFIO) && !model.ID.HasValue) { + return null; + } + return _source.Implementers.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ImplementerFIO) && + x.ImplementerFIO == model.ImplementerFIO) || + model.ID.HasValue && x.ID == model.ID)?.GetViewModel; + } + + public List GetFilteredList(ImplementerSearchModel model) { + if (string.IsNullOrEmpty(model.ImplementerFIO)) { + return new(); + } + return _source.Implementers.Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO)) + .Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() { + return _source.Implementers.Select(x => x.GetViewModel).ToList(); + } + + + } +} diff --git a/Diner/DinerShopImplement/Models/Client.cs b/Diner/DinerShopImplement/Models/Client.cs index 9d198de..8cbbea9 100644 --- a/Diner/DinerShopImplement/Models/Client.cs +++ b/Diner/DinerShopImplement/Models/Client.cs @@ -1,4 +1,4 @@ -using DinerContracts.BindingModels; + using DinerContracts.BindingModels; using DinerContracts.ViewModels; using DinerDataModels.Models; using System; @@ -57,6 +57,6 @@ namespace DinerFileImplement.Models { public XElement GetXElement => new("Client", new XAttribute("ID", ID), new XElement("ClientFIO", ClientFIO), new XElement("Email", Email), - new XElement("Password", Password.ToString())); + new XElement("Password", Password)); } } diff --git a/Diner/DinerShopImplement/Models/Implementer.cs b/Diner/DinerShopImplement/Models/Implementer.cs new file mode 100644 index 0000000..5775c76 --- /dev/null +++ b/Diner/DinerShopImplement/Models/Implementer.cs @@ -0,0 +1,70 @@ +using DinerContracts.BindingModels; +using DinerContracts.ViewModels; +using DinerDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace DinerFileImplement.Models { + public class Implementer : IImplementerModel { + public string ImplementerFIO { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + + public int WorkExperience { get; set; } + + public int Qualification { get; set; } + + public int ID { get; set; } + + public static Implementer? Create(ImplementerBindingModel? model) { + if (model == null) { + return null; + } + return new Implementer() { + ImplementerFIO = model.ImplementerFIO, + Password = model.Password, + WorkExperience = model.WorkExperience, + Qualification = model.Qualification, + ID = model.ID + }; + } + public static Implementer? Create(XElement element) { + if (element == null) { + return null; + } + return new Implementer() { + ImplementerFIO = element.Element("ImplementerFIO")!.Value, + Password = element.Element("Password")!.Value, + WorkExperience = Convert.ToInt32(element.Element("WorkExperience")!.Value), + Qualification = Convert.ToInt32(element.Element("Qualification")!.Value), + ID = Convert.ToInt32(element.Element("ID")!.Value) + }; + } + public void Update (ImplementerBindingModel? model) { + if (model == null) { + return; + } + ImplementerFIO = model.ImplementerFIO; + Password = model.Password; + Qualification = model.Qualification; + } + + public ImplementerViewModel GetViewModel => new() { + ImplementerFIO = ImplementerFIO, + Password = Password, + Qualification = Qualification, + WorkExperience = WorkExperience, + ID = ID + }; + + public XElement GetXElement => new("Implementer", new XAttribute("ID", ID), + new XElement("ImplementerFIO", ImplementerFIO), + new XElement("Password", Password), + new XElement("Qualification", Qualification.ToString()), + new XElement("WorkExperience", WorkExperience.ToString()), + new XAttribute("ID", ID)); + } +} diff --git a/Diner/DinerShopImplement/Models/Order.cs b/Diner/DinerShopImplement/Models/Order.cs index 16a97fc..13d0045 100644 --- a/Diner/DinerShopImplement/Models/Order.cs +++ b/Diner/DinerShopImplement/Models/Order.cs @@ -8,13 +8,17 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; +using System.Xml.Schema; namespace DinerFileImplement.Models { - internal class Order : IOrderModel - { + internal class Order : IOrderModel { public int SnackID { get; private set; } + public int ClientID { get; private set; } + + public int ImplementerID { get; set; } + public int Count { get; set; } public double Sum { get; private set; } @@ -27,6 +31,11 @@ namespace DinerFileImplement.Models public int ID { get; private set; } + public string? ProductName { get; private set; } + + public string ClientFIO { get; private set; } + + public string ImplementerFIO { get; private set; } public static Order? Create(OrderBindingModel? model) { @@ -40,6 +49,8 @@ namespace DinerFileImplement.Models Status = model.Status, DateCreate = model.DateCreate, DateImplement = model.DateImplement, + ClientID = model.ClientID, + ImplementerID = model.ImplementerID }; } public static Order? Create(XElement element) { @@ -54,6 +65,8 @@ namespace DinerFileImplement.Models DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value), DateImplement = string.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null : Convert.ToDateTime(element.Element("DateImplement")!.Value), + ClientID = Convert.ToInt32(element.Element("ClientID")!.Value), + ImplementerID = Convert.ToInt32(element.Element("ImplementerID")!.Value) }; } public void Update(OrderBindingModel? model) @@ -71,6 +84,10 @@ namespace DinerFileImplement.Models Status = Status, DateCreate = DateCreate, DateImplement = DateImplement, + ClientID = ClientID, + ImplementerID = ImplementerID, + ClientFIO = ClientFIO, + ImplementerFIO = ImplementerFIO }; public XElement GetXElement => new("Order", new XAttribute("ID", ID), new XElement("SnackID", SnackID), @@ -78,7 +95,11 @@ namespace DinerFileImplement.Models new XElement("Sum", Sum.ToString()), new XElement("Status", Status.ToString()), new XElement("DateCreate", DateCreate.ToString()), - new XElement("DateImplement", DateImplement.ToString())); + new XElement("DateImplement", DateImplement.ToString()), + new XElement("ClientID", ClientID.ToString()), + new XElement("ImplementerID", ImplementerID.ToString()), + new XElement("ClientFIO", ClientFIO), + new XElement("ImplementerFIO", ImplementerFIO)); } } diff --git a/Diner/DinerView/Program.cs b/Diner/DinerView/Program.cs index 69d9bf1..0e28659 100644 --- a/Diner/DinerView/Program.cs +++ b/Diner/DinerView/Program.cs @@ -39,14 +39,17 @@ namespace DinerView }); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/Diner/DineryBusinessLogic/BusinessLogic/ClientLogic.cs b/Diner/DineryBusinessLogic/BusinessLogic/ClientLogic.cs index b2f38bd..369d38c 100644 --- a/Diner/DineryBusinessLogic/BusinessLogic/ClientLogic.cs +++ b/Diner/DineryBusinessLogic/BusinessLogic/ClientLogic.cs @@ -55,7 +55,7 @@ namespace DineryBusinessLogic.BusinessLogic { if (model == null) { throw new ArgumentNullException(nameof(model)); } - _logger.LogInformation($"ReadElement. Login:{model.ClientFIO}.ID:{model.ID}"); + _logger.LogInformation($"ReadElement. Login:{model.Email}.ID:{model.ID}"); var element = _storage.GetElement(model); if (element == null) { _logger.LogWarning("ReadElement. element not found"); @@ -69,7 +69,7 @@ namespace DineryBusinessLogic.BusinessLogic { _logger.LogInformation($"ReadList. CLientID:{model?.ID}"); var list = model == null ? _storage.GetFullList() : _storage.GetFilteredList(model); if (list == null) { - _logger.LogWarning("ReadList. return nell list"); + _logger.LogWarning("ReadList. return null list"); return null; } _logger.LogInformation($"ReadList. Count:{list.Count}"); @@ -98,9 +98,9 @@ namespace DineryBusinessLogic.BusinessLogic { } _logger.LogInformation($"Client. ID:{model.ID}.FIO:{model.ClientFIO}.Email:{model.Email}.Password:{model.Password}"); var element = _storage.GetElement(new ClientSearchModel { - ClientFIO = model.ClientFIO, + Email = model.Email, }); - if (element != null && element.ClientFIO == model.ClientFIO) { + if (element != null && element.Email == model.Email) { throw new InvalidOperationException("Клиент с таким логином уже есть"); } } diff --git a/Diner/DineryBusinessLogic/BusinessLogic/ImplementerLogic.cs b/Diner/DineryBusinessLogic/BusinessLogic/ImplementerLogic.cs new file mode 100644 index 0000000..6bca427 --- /dev/null +++ b/Diner/DineryBusinessLogic/BusinessLogic/ImplementerLogic.cs @@ -0,0 +1,111 @@ +using DinerContracts.BindingModels; +using DinerContracts.BusinessLogicsContracts; +using DinerContracts.SearchModels; +using DinerContracts.StoragesContracts; +using DinerContracts.ViewModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Metadata.Ecma335; +using System.Text; +using System.Threading.Tasks; + +namespace DineryBusinessLogic.BusinessLogic { + public class ImplementerLogic : IImplementerLogic { + + private readonly ILogger _logger; + private readonly IImplementerStorage _storage; + + public ImplementerLogic(ILogger logger, IImplementerStorage storage) { + _logger = logger; + _storage = storage; + } + + public bool Create(ImplementerBindingModel model) { + CheckModel(model); + if (_storage.Insert(model) == null) { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Delete(ImplementerBindingModel model) { + CheckModel(model, false); + _logger.LogInformation($"Delete. ID:{model.ID}"); + if (_storage.Delete(model) == null) { + _logger.LogWarning("Delete operation failed"); + return false; + } + return false; + } + + public bool Update(ImplementerBindingModel model) { + CheckModel(model); + if (_storage.Update(model) == null) { + _logger.LogWarning("Update operation failde"); + return false; + } + return true; + } + + public ImplementerViewModel? ReadElement(ImplementerSearchModel model) { + if (model == null) { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation($"ReadElement. FIO:{model.ImplementerFIO}.ID:{model.ID}"); + var element = _storage.GetElement(model); + if (element == null) { + _logger.LogWarning("ReadElement. element not fount"); + return null; + } + _logger.LogInformation($"ReadElement. find.ID:{element.ID}"); + return element; + } + + public List? ReadList(ImplementerSearchModel? model) { + _logger.LogInformation($"ReadList. ImplementerID:{model?.ID}"); + var list = model == null ? _storage.GetFullList() : _storage.GetFilteredList(model); + if (list == null) { + _logger.LogWarning("ReadList. return null list"); + return null; + } + _logger.LogInformation($"ReadList. Count:{list.Count}"); + return list; + } + + + private void CheckModel(ImplementerBindingModel model, bool withParams = true) { + if (model == null) { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) { + return; + } + if (string.IsNullOrEmpty(model.ImplementerFIO)) { + throw new ArgumentNullException("Нет ФИО исполнителя", nameof(model.ImplementerFIO)); + } + if (string.IsNullOrEmpty(model.Password)) { + throw new ArgumentNullException("Нет пароля"); + } + if (string.IsNullOrEmpty((model.WorkExperience).ToString())) { + throw new ArgumentNullException("Не указан стаж"); + } + if (string.IsNullOrEmpty((model.Qualification).ToString())) { + throw new ArgumentNullException("Нет квалификации"); + } + if (string.IsNullOrEmpty((model.ID).ToString())) { + throw new ArgumentNullException("Нет ID пользователя", nameof(model.ID)); + } + _logger.LogInformation($"Implementer. ID:{model.ID}.ImplementerFIO:{model.ImplementerFIO}.WorkExperience:{model.WorkExperience}." + + $"Qualification:{model.Qualification}"); + var element = _storage.GetElement(new ImplementerSearchModel { + ImplementerFIO = model.ImplementerFIO + }); + if (element != null && element.ImplementerFIO == model.ImplementerFIO) { + throw new InvalidOperationException("Исполнитель с таким ФИО уже есть"); + } + } + } +} diff --git a/Diner/DineryBusinessLogic/BusinessLogic/OrderLogic.cs b/Diner/DineryBusinessLogic/BusinessLogic/OrderLogic.cs index db13088..4e1096e 100644 --- a/Diner/DineryBusinessLogic/BusinessLogic/OrderLogic.cs +++ b/Diner/DineryBusinessLogic/BusinessLogic/OrderLogic.cs @@ -45,7 +45,21 @@ namespace DineryBusinessLogic.BusinessLogic return StatusUpdate(model, OrderStatus.Готов); } - public List? ReadList(OrderSearchModel? model) + public OrderViewModel? ReadElement(OrderSearchModel model) { + if (model == null) { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation($"ReadElement. ImplementerLogin:{model.ImplementerID}.ID:{model.ID}"); + var element = _orderStorage.GetElement(model); + if (element == null) { + _logger.LogWarning("ReadElement. element not found"); + return null; + } + _logger.LogInformation($"ReadElement. findID:{element.ID}"); + return element; + } + + public List? ReadList(OrderSearchModel? model) { _logger.LogInformation("ReadList. ID:{ID}", model?.ID); var list = model == null? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model); @@ -72,10 +86,14 @@ namespace DineryBusinessLogic.BusinessLogic if (model.ClientID < 0) { throw new ArgumentNullException("Некорректный идентификатор у клиента", nameof(model.ClientID)); } + if (model.ImplementerID < 0) { + throw new ArgumentNullException("Некорректный идентификатор у исполнителя", nameof(model.ImplementerID)); + } _logger.LogInformation("Order. SnackID:{SnackID}. Count:{Count}. Sum:{Sum}. Status:{Status}. " + - "DateCreate:{DateCreate}. DateImplement:{DateImplement}. ID:{ID}, ClientId: {ClientId}", + "DateCreate:{DateCreate}. DateImplement:{DateImplement}. ID:{ID}. ClientId: {ClientId}. " + + "ImplementerID: {ImplementerId}", model.SnackID, model.Count, model.Sum, model.Status, model.DateCreate, model.DateImplement, model.ID, - model.ClientID); + model.ClientID, model.ImplementerID); } private bool StatusUpdate(OrderBindingModel model, OrderStatus newOrderStatus) { CheckModel(model, false); diff --git a/Diner/DineryBusinessLogic/BusinessLogic/WorkModelling.cs b/Diner/DineryBusinessLogic/BusinessLogic/WorkModelling.cs new file mode 100644 index 0000000..2044fc1 --- /dev/null +++ b/Diner/DineryBusinessLogic/BusinessLogic/WorkModelling.cs @@ -0,0 +1,121 @@ +using DinerContracts.BindingModels; +using DinerContracts.BusinessLogicsContacts; +using DinerContracts.BusinessLogicsContracts; +using DinerContracts.SearchModels; +using DinerContracts.ViewModels; +using DinerDataModels.Enums; +using DocumentFormat.OpenXml.Office2010.Excel; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DineryBusinessLogic.BusinessLogic { + public class WorkModelling : IWorkProcess { + + private readonly ILogger _logger; + + private readonly Random _rnd; + + private IOrderLogic? _orderLogic; + + public WorkModelling(ILogger logger) { + _logger = logger; + _rnd = new Random(1000); + } + + public void Work(IImplementerLogic implementerLogic, IOrderLogic orderLogic) { + _orderLogic = orderLogic; + var implementers = implementerLogic.ReadList(null); + if (implementers == null) { + _logger.LogWarning("DoWork. Implementers is null"); + return; + } + var orders = _orderLogic.ReadList(new OrderSearchModel { + Status = OrderStatus.Принят + }); + if (orders == null || orders.Count == 0) { + _logger.LogWarning("DoWork. Orders is null or empty"); + return; + } + _logger.LogDebug($"DoWork for {orders.Count} orders"); + foreach (var implementer in implementers) { + Task.Run(() => WorkerWorkAsync(implementer, orders)); + } + } + + // Иммитация работы исполнителя + private async Task WorkerWorkAsync(ImplementerViewModel implementer, List orders) { + if (_orderLogic == null || implementer == null) { + return; + } + await RunOrderInWork(implementer); + await Task.Run(() => { + foreach (var order in orders) { + try { + _logger.LogDebug($"DoWork. Worker {implementer.ID} try get order {order.ID}"); + // пытаемся назначить заказ на исполнителя + _orderLogic.TakeOrderInWork(new OrderBindingModel { + ID = order.ID, + ImplementerID = implementer.ID + }); + // делаем работу + Thread.Sleep(implementer.WorkExperience + _rnd.Next(100, 1000) * order.Count); + _logger.LogDebug($"DoWork. Worker {implementer.ID} finish order {order.ID}"); + _orderLogic.FinishOrder(new OrderBindingModel { + ID = order.ID, + }); + } + // кто-то мог уже перехватить заказ, игнорируем ошибку + catch (InvalidOperationException ex) { + _logger.LogWarning(ex, "Error try get work"); + } + // заканчиваем выполнение имитации в случае иной ошибки + catch (Exception ex) { + _logger.LogError(ex, "Error while do work"); + throw; + } + // отдыхаем + Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100)); + } + }); + } + + // Ищем заказ, которые уже в работе(вдруг исполнителя прервали) + private async Task RunOrderInWork(ImplementerViewModel implementer) { + if (_orderLogic == null || implementer == null) { + return; + } + try { + var runOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel { + ImplementerID = implementer.ID, + Status = OrderStatus.Выполняется + })); + if (runOrder == null) { + return; + } + + _logger.LogDebug($"DoWork. Worker {implementer.ID} back to order {runOrder.ID}"); + // доделываем работу + Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count); + _logger.LogDebug($"DoWork. Worker{implementer.ID} finish order {runOrder.ID}"); + _orderLogic.FinishOrder(new OrderBindingModel { + ID = runOrder.ID + }); + // отдыхаем + Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100)); + } + // заказа может не быть, просто игнорируем ошибку + catch (InvalidOperationException ex) { + _logger.LogWarning(ex, "Error try get work"); + } + // а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации + catch (Exception ex) { + _logger.LogError(ex, "Error while do work"); + throw; + } + } + } +}