From d8cc35c62725687bad1f2a395ec6cf39e36b6818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BE=D0=BB=D0=BE=D0=B4=D1=8F?= Date: Wed, 19 Apr 2023 19:38:34 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=D0=B5=D0=BB=D1=8F=20=D0=B8=20=D0=B5=D0=B3=D0=BE=20=D0=BB?= =?UTF-8?q?=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/OrderLogic.cs | 56 +++- .../BusinessLogics/WorkModeling.cs | 157 ++++++++++ .../BindingModels/ImplementerBindingModel.cs | 22 ++ .../BindingModels/OrderBindingModel.cs | 6 +- .../IImplementerLogic.cs | 24 ++ .../BusinessLogicsContracts/IOrderLogic.cs | 1 + .../BusinessLogicsContracts/IWorkProcess.cs | 13 + .../SearchModel/ImplementerSearchModel.cs | 17 ++ .../SearchModel/OrderSearchModel.cs | 5 +- .../StoragesContracts/IImplementerStorage.cs | 26 ++ .../ViewModel/ImplementerViewModel.cs | 27 ++ .../ViewModel/OrderViewModel.cs | 9 +- .../Models/IImplementerModel.cs | 19 ++ .../Models/IOrderModel.cs | 2 + .../DataListSingleton.cs | 2 + .../Implements/ImplementerStorage.cs | 126 ++++++++ .../Implements/OrderStorage.cs | 6 +- .../Models/Implementer.cs | 55 ++++ .../AbstractAutoListImplement/Models/Order.cs | 7 + .../AutoPlantDataBase.cs | 1 + .../Implements/ImplementerStorage.cs | 98 +++++++ .../Implements/OrderStorage.cs | 22 +- .../20230419163758_addImp.Designer.cs | 268 ++++++++++++++++++ .../Migrations/20230419163758_addImp.cs | 78 +++++ .../AutoPlantDataBaseModelSnapshot.cs | 46 +++ .../Models/Implementer.cs | 63 ++++ .../Models/Order.cs | 9 + .../DataFileSingleton.cs | 11 +- .../Implements/ImplementerStorage.cs | 90 ++++++ .../Implements/OrderStorage.cs | 6 +- .../Models/Implementer.cs | 77 +++++ .../Models/Order.cs | 15 +- .../Controllers/ImplementerController.cs | 107 +++++++ 33 files changed, 1445 insertions(+), 26 deletions(-) create mode 100644 AutomobilePlant/AbstractAutoBusinessLogic/BusinessLogics/WorkModeling.cs create mode 100644 AutomobilePlant/AbstractAutoContracts/BindingModels/ImplementerBindingModel.cs create mode 100644 AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IImplementerLogic.cs create mode 100644 AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IWorkProcess.cs create mode 100644 AutomobilePlant/AbstractAutoContracts/SearchModel/ImplementerSearchModel.cs create mode 100644 AutomobilePlant/AbstractAutoContracts/StoragesContracts/IImplementerStorage.cs create mode 100644 AutomobilePlant/AbstractAutoContracts/ViewModel/ImplementerViewModel.cs create mode 100644 AutomobilePlant/AbstractAutoDataModels/Models/IImplementerModel.cs create mode 100644 AutomobilePlant/AbstractAutoListImplement/Implements/ImplementerStorage.cs create mode 100644 AutomobilePlant/AbstractAutoListImplement/Models/Implementer.cs create mode 100644 AutomobilePlant/AutomobilePlantDataBaseImplements/Implements/ImplementerStorage.cs create mode 100644 AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/20230419163758_addImp.Designer.cs create mode 100644 AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/20230419163758_addImp.cs create mode 100644 AutomobilePlant/AutomobilePlantDataBaseImplements/Models/Implementer.cs create mode 100644 AutomobilePlant/AutomomilePlantFileImplement/Implements/ImplementerStorage.cs create mode 100644 AutomobilePlant/AutomomilePlantFileImplement/Models/Implementer.cs create mode 100644 AutomobilePlant/AutoplantRestApi/Controllers/ImplementerController.cs diff --git a/AutomobilePlant/AbstractAutoBusinessLogic/BusinessLogics/OrderLogic.cs b/AutomobilePlant/AbstractAutoBusinessLogic/BusinessLogics/OrderLogic.cs index 052f00d..11b020b 100644 --- a/AutomobilePlant/AbstractAutoBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/AutomobilePlant/AbstractAutoBusinessLogic/BusinessLogics/OrderLogic.cs @@ -45,28 +45,50 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics return true; } + public bool StatusUpdate(OrderBindingModel model, OrderStatus newStatus) { - CheckModel(model); - - if (model.Status + 1 != newStatus) + var viewModel = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); + if (viewModel == null) { - _logger.LogWarning("Status update to " + newStatus.ToString() + " operation failed. Order status incorrect."); + throw new ArgumentNullException(nameof(model)); + } + if (viewModel.Status + 1 != newStatus) + { + _logger.LogWarning("Update operation failed. Order status incorrect."); return false; } - model.Status = newStatus; - - if (model.Status == OrderStatus.Выдан) + model.DateCreate = viewModel.DateCreate; + model.Sum = viewModel.Sum; + model.Count = viewModel.Count; + model.DateImplement = viewModel.DateImplement; + model.CarId = viewModel.CarId; + model.CarName = viewModel.CarName; + model.ClientId=viewModel.ClientId; + model.ClientName = viewModel.ClientName; + if (viewModel.ImplementerId.HasValue) + { + model.ImplementerId = viewModel.ImplementerId; + } + if(!string.IsNullOrEmpty(viewModel.ImplementerName)){ + model.ImplementerName = viewModel.ImplementerName; + } + if (model.Status == OrderStatus.Готов) { model.DateImplement = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc); + } + else + { + model.DateImplement = viewModel.DateImplement; + } + CheckModel(model); if (_orderStorage.Update(model) == null) { model.Status--; _logger.LogWarning("Update operation failed"); return false; } - return true; } @@ -95,7 +117,7 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics _logger.LogWarning("ReadList return null list"); return null; } - + _logger.LogInformation("ReadList. Count:{Count}", list.Count); return list; } @@ -128,5 +150,21 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics _logger.LogInformation("Order. OrderId:{Id}.Sum:{ Sum}. WorkId: { WorkId}", model.Id, model.Sum, model.Id); } + + public OrderViewModel? ReadElement(OrderSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + var element = _orderStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } } } diff --git a/AutomobilePlant/AbstractAutoBusinessLogic/BusinessLogics/WorkModeling.cs b/AutomobilePlant/AbstractAutoBusinessLogic/BusinessLogics/WorkModeling.cs new file mode 100644 index 0000000..02f0ad3 --- /dev/null +++ b/AutomobilePlant/AbstractAutoBusinessLogic/BusinessLogics/WorkModeling.cs @@ -0,0 +1,157 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.BusinessLogicsContracts; +using AutomobilePlantContracts.SearchModel; +using AutomobilePlantContracts.ViewModel; +using AutomobilePlantDataModels.Enums; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantBusinessLogic.BusinessLogics +{ + public class WorkModeling : IWorkProcess + { + private readonly ILogger _logger; + + private readonly Random _rnd; + + private IOrderLogic? _orderLogic; + + public WorkModeling(ILogger logger) + { + _logger = logger; + _rnd = new Random(1000); + } + + public void DoWork(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 {Count} orders", orders.Count); + 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 {Id} try get order {Order}", implementer.Id, order.Id); + // пытаемся назначить заказ на исполнителя + _orderLogic.TakeOrderInWork(new OrderBindingModel + { + Id = order.Id, + ImplementerId = implementer.Id, + ImplementerName = implementer.ImplementerFIO + + + }); + // делаем работу + Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count); + _logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id); + _orderLogic.FinishOrder(new OrderBindingModel + { + Id = order.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; + } + + } + }); + } + + /// + /// Ищем заказ, которые уже в работе (вдруг исполнителя прервали) + /// + /// + /// + 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 {Id} back to order {Order}", implementer.Id, runOrder.Id); + // доделываем работу + Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count); + _logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, 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; + } + } + } +} diff --git a/AutomobilePlant/AbstractAutoContracts/BindingModels/ImplementerBindingModel.cs b/AutomobilePlant/AbstractAutoContracts/BindingModels/ImplementerBindingModel.cs new file mode 100644 index 0000000..f9d8331 --- /dev/null +++ b/AutomobilePlant/AbstractAutoContracts/BindingModels/ImplementerBindingModel.cs @@ -0,0 +1,22 @@ +using AutomobilePlantDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantContracts.BindingModels +{ + public class ImplementerBindingModel : IImplementerModel + { + public int Id { get; set; } + + public string ImplementerFIO { get; set; } = string.Empty; + + public string Password { get; set; } = string.Empty; + + public int WorkExperience { get; set; } + + public int Qualification { get; set; } + } +} diff --git a/AutomobilePlant/AbstractAutoContracts/BindingModels/OrderBindingModel.cs b/AutomobilePlant/AbstractAutoContracts/BindingModels/OrderBindingModel.cs index 1d6edc7..95aebdf 100644 --- a/AutomobilePlant/AbstractAutoContracts/BindingModels/OrderBindingModel.cs +++ b/AutomobilePlant/AbstractAutoContracts/BindingModels/OrderBindingModel.cs @@ -12,13 +12,15 @@ namespace AutomobilePlantContracts.BindingModels { public int Id { get; set; } public int CarId { get; set; } - public string CarName { get; set; } = string.Empty; public int ClientId { get; set; } public string ClientName { get; set; } = string.Empty; + public int? ImplementerId { get; set; } + public string? ImplementerName { get; set; } = string.Empty; + public string CarName { get; set; } = string.Empty; public int Count { get; set; } public double Sum { get; set; } public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; - public DateTime DateCreate { get; set; } = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc); + public DateTime DateCreate { get; set; } = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc); public DateTime? DateImplement { get; set; } } } diff --git a/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IImplementerLogic.cs b/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IImplementerLogic.cs new file mode 100644 index 0000000..8e0d3e9 --- /dev/null +++ b/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IImplementerLogic.cs @@ -0,0 +1,24 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.SearchModel; +using AutomobilePlantContracts.ViewModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantContracts.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/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IOrderLogic.cs b/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IOrderLogic.cs index 60238ac..713b474 100644 --- a/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IOrderLogic.cs +++ b/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IOrderLogic.cs @@ -12,6 +12,7 @@ namespace AutomobilePlantContracts.BusinessLogicsContracts public interface IOrderLogic { List? ReadList(OrderSearchModel? model); + OrderViewModel? ReadElement(OrderSearchModel model); bool CreateOrder(OrderBindingModel model); bool TakeOrderInWork(OrderBindingModel model); bool FinishOrder(OrderBindingModel model); diff --git a/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IWorkProcess.cs b/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IWorkProcess.cs new file mode 100644 index 0000000..e82acc9 --- /dev/null +++ b/AutomobilePlant/AbstractAutoContracts/BusinessLogicsContracts/IWorkProcess.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantContracts.BusinessLogicsContracts +{ + public interface IWorkProcess + { + void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic); + } +} diff --git a/AutomobilePlant/AbstractAutoContracts/SearchModel/ImplementerSearchModel.cs b/AutomobilePlant/AbstractAutoContracts/SearchModel/ImplementerSearchModel.cs new file mode 100644 index 0000000..12a4294 --- /dev/null +++ b/AutomobilePlant/AbstractAutoContracts/SearchModel/ImplementerSearchModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantContracts.SearchModel +{ + public class ImplementerSearchModel + { + public int? Id { get; set; } + + public string? ImplementerFIO { get; set; } + + public string? Password { get; set; } + } +} diff --git a/AutomobilePlant/AbstractAutoContracts/SearchModel/OrderSearchModel.cs b/AutomobilePlant/AbstractAutoContracts/SearchModel/OrderSearchModel.cs index 353ff1e..aa607a5 100644 --- a/AutomobilePlant/AbstractAutoContracts/SearchModel/OrderSearchModel.cs +++ b/AutomobilePlant/AbstractAutoContracts/SearchModel/OrderSearchModel.cs @@ -1,4 +1,5 @@ -using System; +using AutomobilePlantDataModels.Enums; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -10,6 +11,8 @@ namespace AutomobilePlantContracts.SearchModel { public int? Id { get; set; } public int? ClientId { get; set; } + public int? ImplementerId { get; set; } + public OrderStatus Status { get; set; } public DateTime? DateFrom { get; set; } public DateTime? DateTo { get; set; } diff --git a/AutomobilePlant/AbstractAutoContracts/StoragesContracts/IImplementerStorage.cs b/AutomobilePlant/AbstractAutoContracts/StoragesContracts/IImplementerStorage.cs new file mode 100644 index 0000000..03804a6 --- /dev/null +++ b/AutomobilePlant/AbstractAutoContracts/StoragesContracts/IImplementerStorage.cs @@ -0,0 +1,26 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.SearchModel; +using AutomobilePlantContracts.ViewModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantContracts.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/AutomobilePlant/AbstractAutoContracts/ViewModel/ImplementerViewModel.cs b/AutomobilePlant/AbstractAutoContracts/ViewModel/ImplementerViewModel.cs new file mode 100644 index 0000000..4f3810a --- /dev/null +++ b/AutomobilePlant/AbstractAutoContracts/ViewModel/ImplementerViewModel.cs @@ -0,0 +1,27 @@ +using AutomobilePlantDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantContracts.ViewModel +{ + public class ImplementerViewModel : IImplementerModel + { + public int Id { get; set; } + + [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; } + } +} diff --git a/AutomobilePlant/AbstractAutoContracts/ViewModel/OrderViewModel.cs b/AutomobilePlant/AbstractAutoContracts/ViewModel/OrderViewModel.cs index 5ccebc4..cfcd8fd 100644 --- a/AutomobilePlant/AbstractAutoContracts/ViewModel/OrderViewModel.cs +++ b/AutomobilePlant/AbstractAutoContracts/ViewModel/OrderViewModel.cs @@ -13,12 +13,15 @@ namespace AutomobilePlantContracts.ViewModel { [DisplayName("Номер")] public int Id { get; set; } + [DisplayName("Клиент")] + public string ClientName { get; set; } = string.Empty; + public int ClientId { get; set; } + public int? ImplementerId { get; set; } + [DisplayName("Исполнитель")] + public string? ImplementerName { get; set; } = string.Empty; public int CarId { get; set; } [DisplayName("Изделие")] public string CarName { get; set; } = string.Empty; - public int ClientId { get; set; } - [DisplayName("Клиент")] - public string ClientName { get; set; } = string.Empty; [DisplayName("Количество")] public int Count { get; set; } [DisplayName("Сумма")] diff --git a/AutomobilePlant/AbstractAutoDataModels/Models/IImplementerModel.cs b/AutomobilePlant/AbstractAutoDataModels/Models/IImplementerModel.cs new file mode 100644 index 0000000..4988582 --- /dev/null +++ b/AutomobilePlant/AbstractAutoDataModels/Models/IImplementerModel.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantDataModels.Models +{ + public interface IImplementerModel : IId + { + string ImplementerFIO { get; } + + string Password { get; } + + int WorkExperience { get; } + + int Qualification { get; } + } +} diff --git a/AutomobilePlant/AbstractAutoDataModels/Models/IOrderModel.cs b/AutomobilePlant/AbstractAutoDataModels/Models/IOrderModel.cs index 4481ba0..6bfc1c0 100644 --- a/AutomobilePlant/AbstractAutoDataModels/Models/IOrderModel.cs +++ b/AutomobilePlant/AbstractAutoDataModels/Models/IOrderModel.cs @@ -13,6 +13,8 @@ namespace AutomobilePlantDataModels.Models string CarName { get; } int ClientId { get; } string ClientName { get; } + int? ImplementerId { get; } + string? ImplementerName { get; } int Count { get; } double Sum { get; } OrderStatus Status { get; } diff --git a/AutomobilePlant/AbstractAutoListImplement/DataListSingleton.cs b/AutomobilePlant/AbstractAutoListImplement/DataListSingleton.cs index 07282df..0b4e049 100644 --- a/AutomobilePlant/AbstractAutoListImplement/DataListSingleton.cs +++ b/AutomobilePlant/AbstractAutoListImplement/DataListSingleton.cs @@ -14,12 +14,14 @@ namespace AutomobilePlantListImplement public List Orders { get; set; } public List Cars { get; set; } public List Clients { get; set; } + public List Implementers { get; set; } private DataListSingleton() { Components = new List(); Orders = new List(); Cars = new List(); Clients = new List(); + Implementers = new List(); } public static DataListSingleton GetInstance() { diff --git a/AutomobilePlant/AbstractAutoListImplement/Implements/ImplementerStorage.cs b/AutomobilePlant/AbstractAutoListImplement/Implements/ImplementerStorage.cs new file mode 100644 index 0000000..2051020 --- /dev/null +++ b/AutomobilePlant/AbstractAutoListImplement/Implements/ImplementerStorage.cs @@ -0,0 +1,126 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.SearchModel; +using AutomobilePlantContracts.StoragesContracts; +using AutomobilePlantContracts.ViewModel; +using AutomobilePlantListImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantListImplement.Implements +{ + public class ImplementerStorage : IImplementerStorage + { + private readonly DataListSingleton _source; + + public ImplementerStorage() + { + _source = DataListSingleton.GetInstance(); + } + + public List GetFullList() + { + var result = new List(); + + foreach (var implementer in _source.Implementers) + { + result.Add(implementer.GetViewModel); + } + + return result; + } + + public List GetFilteredList(ImplementerSearchModel model) + { + var result = new List(); + + if (string.IsNullOrEmpty(model.ImplementerFIO) && string.IsNullOrEmpty(model.Password)) + { + return result; + } + + foreach (var implementer in _source.Implementers) + { + if (implementer.ImplementerFIO.Contains(model.ImplementerFIO) || implementer.Password.Contains(model.Password)) + { + result.Add(implementer.GetViewModel); + } + } + + return result; + } + + 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 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; + } + } +} diff --git a/AutomobilePlant/AbstractAutoListImplement/Implements/OrderStorage.cs b/AutomobilePlant/AbstractAutoListImplement/Implements/OrderStorage.cs index 525f193..7b1d89b 100644 --- a/AutomobilePlant/AbstractAutoListImplement/Implements/OrderStorage.cs +++ b/AutomobilePlant/AbstractAutoListImplement/Implements/OrderStorage.cs @@ -35,7 +35,7 @@ namespace AutomobilePlantListImplement.Implements { var result = new List(); - if (model is null) + if (!model.Id.HasValue) { return result; } @@ -46,7 +46,7 @@ namespace AutomobilePlantListImplement.Implements { result.Add(order.GetViewModel); continue; } - if ( order.DateCreate > model.DateFrom && order.DateCreate < model.DateTo) + if (model.Id.HasValue && order.Id == model.Id && order.DateCreate > model.DateFrom && order.DateCreate < model.DateTo) { result.Add(order.GetViewModel); } @@ -124,5 +124,7 @@ namespace AutomobilePlantListImplement.Implements return null; } + + } } diff --git a/AutomobilePlant/AbstractAutoListImplement/Models/Implementer.cs b/AutomobilePlant/AbstractAutoListImplement/Models/Implementer.cs new file mode 100644 index 0000000..93e9a7d --- /dev/null +++ b/AutomobilePlant/AbstractAutoListImplement/Models/Implementer.cs @@ -0,0 +1,55 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.ViewModel; +using AutomobilePlantDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantListImplement.Models +{ + public class Implementer : IImplementerModel + { + public int Id { get; private set; } + public string ImplementerFIO { get; private set; } = string.Empty; + public int WorkExperience { get; set; } + + public int Qualification { get; set; } + public string Password { get; private set; } = string.Empty; + public static Implementer? Create(ImplementerBindingModel? model) + { + if (model == null) + { + return null; + } + return new Implementer() + { + Id = model.Id, + ImplementerFIO = model.ImplementerFIO, + WorkExperience = model.WorkExperience, + Qualification = model.Qualification, + Password = model.Password + }; + } + public void Update(ImplementerBindingModel? model) + { + if (model == null) + { + return; + } + ImplementerFIO = model.ImplementerFIO; + WorkExperience = model.WorkExperience; + Qualification = model.Qualification; + Password = model.Password; + } + public ImplementerViewModel GetViewModel => new() + { + Id = Id, + ImplementerFIO = ImplementerFIO, + WorkExperience = WorkExperience, + Qualification=Qualification, + Password = Password + }; + } +} diff --git a/AutomobilePlant/AbstractAutoListImplement/Models/Order.cs b/AutomobilePlant/AbstractAutoListImplement/Models/Order.cs index 362fe1e..dba159b 100644 --- a/AutomobilePlant/AbstractAutoListImplement/Models/Order.cs +++ b/AutomobilePlant/AbstractAutoListImplement/Models/Order.cs @@ -16,6 +16,8 @@ namespace AutomobilePlantListImplement.Models public int CarId { get; private set; } public int ClientId { get; private set; } public string ClientName { get; private set; } = string.Empty; + public int? ImplementerId { get; private set; } + public string? ImplementerName { get; private set; } = string.Empty; public string CarName { get; private set; } public int Count { get; private set; } public double Sum { get; private set; } @@ -35,6 +37,8 @@ namespace AutomobilePlantListImplement.Models CarId = model.CarId, ClientId = model.ClientId, CarName = model.CarName, + ImplementerId = model.ImplementerId, + ImplementerName = model.ImplementerName, Count = model.Count, Sum = model.Sum, Status = model.Status, @@ -58,6 +62,9 @@ namespace AutomobilePlantListImplement.Models Id = Id, CarId = CarId, ClientId=ClientId, + ClientName = ClientName, + ImplementerId=ImplementerId, + ImplementerName=ImplementerName, CarName = CarName, Count = Count, Sum = Sum, diff --git a/AutomobilePlant/AutomobilePlantDataBaseImplements/AutoPlantDataBase.cs b/AutomobilePlant/AutomobilePlantDataBaseImplements/AutoPlantDataBase.cs index 199e29f..145f1cc 100644 --- a/AutomobilePlant/AutomobilePlantDataBaseImplements/AutoPlantDataBase.cs +++ b/AutomobilePlant/AutomobilePlantDataBaseImplements/AutoPlantDataBase.cs @@ -28,5 +28,6 @@ namespace AutomobilePlantDataBaseImplements public virtual DbSet Orders { set; get; } public virtual DbSet Clients { set; get; } + public virtual DbSet Implementers { set; get; } } } diff --git a/AutomobilePlant/AutomobilePlantDataBaseImplements/Implements/ImplementerStorage.cs b/AutomobilePlant/AutomobilePlantDataBaseImplements/Implements/ImplementerStorage.cs new file mode 100644 index 0000000..763209f --- /dev/null +++ b/AutomobilePlant/AutomobilePlantDataBaseImplements/Implements/ImplementerStorage.cs @@ -0,0 +1,98 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.SearchModel; +using AutomobilePlantContracts.StoragesContracts; +using AutomobilePlantContracts.ViewModel; +using AutomobilePlantDataBaseImplements.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomobilePlantDataBaseImplements.Implements +{ + public class ImplementerStorage : IImplementerStorage + { + public ImplementerViewModel? Delete(ImplementerBindingModel model) + { + using var context = new AutoPlantDataBase(); + var element = context.Implementers.FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Implementers.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + public ImplementerViewModel? GetElement(ImplementerSearchModel model) + { + if (string.IsNullOrEmpty(model.ImplementerFIO) && !model.Id.HasValue) + { + return null; + } + using var context = new AutoPlantDataBase(); + return context.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) && string.IsNullOrEmpty(model.Password)) + { + return new(); + } + using var context = new AutoPlantDataBase(); + if (!string.IsNullOrEmpty(model.ImplementerFIO)) + { + return context.Implementers + .Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO)) + .Select(x => x.GetViewModel) + .ToList(); + } + + return context.Implementers + .Where(x => x.Password.Contains(model.Password)) + .Select(x => x.GetViewModel) + .ToList(); + + } + + public List GetFullList() + { + using var context = new AutoPlantDataBase(); + return context.Implementers + .Select(x => x.GetViewModel) + .ToList(); + } + + public ImplementerViewModel? Insert(ImplementerBindingModel model) + { + var newImplementer = Implementer.Create(model); + if (newImplementer == null) + { + return null; + } + using var context = new AutoPlantDataBase(); + context.Implementers.Add(newImplementer); + context.SaveChanges(); + return newImplementer.GetViewModel; + } + + public ImplementerViewModel? Update(ImplementerBindingModel model) + { + using var context = new AutoPlantDataBase(); + var implementer = context.Implementers.FirstOrDefault(x => x.Id == model.Id); + if (implementer == null) + { + return null; + } + implementer.Update(model); + context.SaveChanges(); + return implementer.GetViewModel; + } + } +} diff --git a/AutomobilePlant/AutomobilePlantDataBaseImplements/Implements/OrderStorage.cs b/AutomobilePlant/AutomobilePlantDataBaseImplements/Implements/OrderStorage.cs index 5bb7710..8453d74 100644 --- a/AutomobilePlant/AutomobilePlantDataBaseImplements/Implements/OrderStorage.cs +++ b/AutomobilePlant/AutomobilePlantDataBaseImplements/Implements/OrderStorage.cs @@ -32,11 +32,12 @@ namespace AutomobilePlantDataBaseImplements.Implements if (model.DateTo != null && model.DateFrom != null && model.ClientId.HasValue) { return context.Orders - .Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo && x.ClientId==model.ClientId) + .Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo && x.ClientId == model.ClientId) .ToList() .Select(x => x.GetViewModel) .ToList(); } + else if (model.DateTo != null && model.DateFrom != null) { return context.Orders @@ -45,11 +46,20 @@ namespace AutomobilePlantDataBaseImplements.Implements .Select(x => x.GetViewModel) .ToList(); } - return context.Orders + else if (model.ClientId.HasValue) + { + return context.Orders .Where(x => x.ClientId == model.ClientId) .ToList() .Select(x => x.GetViewModel) .ToList(); + } + return context.Orders + .Where(x => x.Status == model.Status) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } public OrderViewModel? GetElement(OrderSearchModel model) @@ -59,6 +69,12 @@ namespace AutomobilePlantDataBaseImplements.Implements return null; } using var context = new AutoPlantDataBase(); + if (model.ImplementerId.HasValue) + { + return context.Orders + .FirstOrDefault(x => x.ImplementerId == model.ImplementerId && x.Status.Equals(model.Status)) + ?.GetViewModel; + } return context.Orders .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) ?.GetViewModel; @@ -114,5 +130,7 @@ namespace AutomobilePlantDataBaseImplements.Implements } return null; } + + } } diff --git a/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/20230419163758_addImp.Designer.cs b/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/20230419163758_addImp.Designer.cs new file mode 100644 index 0000000..6c2959e --- /dev/null +++ b/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/20230419163758_addImp.Designer.cs @@ -0,0 +1,268 @@ +// +using System; +using AutomobilePlantDataBaseImplements; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace AutomobilePlantDataBaseImplements.Migrations +{ + [DbContext(typeof(AutoPlantDataBase))] + [Migration("20230419163758_addImp")] + partial class addImp + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Car", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CarName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("Cars"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.CarComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CarId") + .HasColumnType("integer"); + + b.Property("ComponentId") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CarId"); + + b.HasIndex("ComponentId"); + + b.ToTable("CarComponents"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Cost") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.Property("Qualification") + .HasColumnType("integer"); + + b.Property("WorkExperience") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CarId") + .HasColumnType("integer"); + + b.Property("CarName") + .IsRequired() + .HasColumnType("text"); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("ClientName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("DateCreate") + .HasColumnType("timestamp with time zone"); + + b.Property("DateImplement") + .HasColumnType("timestamp with time zone"); + + b.Property("ImplementerId") + .HasColumnType("integer"); + + b.Property("ImplementerName") + .HasColumnType("text"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Sum") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("CarId"); + + b.HasIndex("ClientId"); + + b.HasIndex("ImplementerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.CarComponent", b => + { + b.HasOne("AutomobilePlantDataBaseImplements.Models.Car", "Car") + .WithMany("Components") + .HasForeignKey("CarId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AutomobilePlantDataBaseImplements.Models.Component", "Component") + .WithMany("CarComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Car"); + + b.Navigation("Component"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Order", b => + { + b.HasOne("AutomobilePlantDataBaseImplements.Models.Car", "car") + .WithMany("Orders") + .HasForeignKey("CarId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AutomobilePlantDataBaseImplements.Models.Client", "client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AutomobilePlantDataBaseImplements.Models.Implementer", "implementer") + .WithMany("Orders") + .HasForeignKey("ImplementerId"); + + b.Navigation("car"); + + b.Navigation("client"); + + b.Navigation("implementer"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Car", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Client", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Component", b => + { + b.Navigation("CarComponents"); + }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Implementer", b => + { + b.Navigation("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/20230419163758_addImp.cs b/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/20230419163758_addImp.cs new file mode 100644 index 0000000..99a444e --- /dev/null +++ b/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/20230419163758_addImp.cs @@ -0,0 +1,78 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace AutomobilePlantDataBaseImplements.Migrations +{ + /// + public partial class addImp : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ImplementerId", + table: "Orders", + type: "integer", + nullable: true); + + migrationBuilder.AddColumn( + name: "ImplementerName", + table: "Orders", + type: "text", + nullable: true); + + migrationBuilder.CreateTable( + name: "Implementers", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ImplementerFIO = table.Column(type: "text", nullable: false), + WorkExperience = table.Column(type: "integer", nullable: false), + Qualification = table.Column(type: "integer", nullable: false), + Password = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Implementers", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Orders_ImplementerId", + table: "Orders", + column: "ImplementerId"); + + migrationBuilder.AddForeignKey( + name: "FK_Orders_Implementers_ImplementerId", + table: "Orders", + column: "ImplementerId", + principalTable: "Implementers", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Orders_Implementers_ImplementerId", + table: "Orders"); + + migrationBuilder.DropTable( + name: "Implementers"); + + migrationBuilder.DropIndex( + name: "IX_Orders_ImplementerId", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "ImplementerId", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "ImplementerName", + table: "Orders"); + } + } +} diff --git a/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/AutoPlantDataBaseModelSnapshot.cs b/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/AutoPlantDataBaseModelSnapshot.cs index ec48f17..90be0b5 100644 --- a/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/AutoPlantDataBaseModelSnapshot.cs +++ b/AutomobilePlant/AutomobilePlantDataBaseImplements/Migrations/AutoPlantDataBaseModelSnapshot.cs @@ -113,6 +113,33 @@ namespace AutomobilePlantDataBaseImplements.Migrations b.ToTable("Components"); }); + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.Property("Qualification") + .HasColumnType("integer"); + + b.Property("WorkExperience") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Order", b => { b.Property("Id") @@ -144,6 +171,12 @@ namespace AutomobilePlantDataBaseImplements.Migrations b.Property("DateImplement") .HasColumnType("timestamp with time zone"); + b.Property("ImplementerId") + .HasColumnType("integer"); + + b.Property("ImplementerName") + .HasColumnType("text"); + b.Property("Status") .HasColumnType("integer"); @@ -156,6 +189,8 @@ namespace AutomobilePlantDataBaseImplements.Migrations b.HasIndex("ClientId"); + b.HasIndex("ImplementerId"); + b.ToTable("Orders"); }); @@ -192,9 +227,15 @@ namespace AutomobilePlantDataBaseImplements.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("AutomobilePlantDataBaseImplements.Models.Implementer", "implementer") + .WithMany("Orders") + .HasForeignKey("ImplementerId"); + b.Navigation("car"); b.Navigation("client"); + + b.Navigation("implementer"); }); modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Car", b => @@ -213,6 +254,11 @@ namespace AutomobilePlantDataBaseImplements.Migrations { b.Navigation("CarComponents"); }); + + modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Implementer", b => + { + b.Navigation("Orders"); + }); #pragma warning restore 612, 618 } } diff --git a/AutomobilePlant/AutomobilePlantDataBaseImplements/Models/Implementer.cs b/AutomobilePlant/AutomobilePlantDataBaseImplements/Models/Implementer.cs new file mode 100644 index 0000000..f0de96d --- /dev/null +++ b/AutomobilePlant/AutomobilePlantDataBaseImplements/Models/Implementer.cs @@ -0,0 +1,63 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.ViewModel; +using AutomobilePlantDataModels.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 AutomobilePlantDataBaseImplements.Models +{ + public class Implementer : IImplementerModel + { + public int Id { get; set; } + + [Required] + public string ImplementerFIO { get; set; } = string.Empty; + + [Required] + public int WorkExperience { get; set; } + [Required] + public int Qualification { get; set; } + + [Required] + public string Password { get; set; } = string.Empty; + + + [ForeignKey("ImplementerId")] + public virtual List Orders { get; set; } = new(); + + public static Implementer Create(ImplementerBindingModel model) + { + return new Implementer() + { + Id = model.Id, + ImplementerFIO = model.ImplementerFIO, + WorkExperience = model.WorkExperience, + Qualification = model.Qualification, + Password = model.Password + }; + } + + public void Update(ImplementerBindingModel model) + { + ImplementerFIO = model.ImplementerFIO; + WorkExperience=model.WorkExperience; + Qualification=model.Qualification; + Password = model.Password; + } + + public ImplementerViewModel GetViewModel => new() + { + Id = Id, + ImplementerFIO = ImplementerFIO, + WorkExperience = WorkExperience, + Qualification=Qualification, + Password = Password + }; + + } +} diff --git a/AutomobilePlant/AutomobilePlantDataBaseImplements/Models/Order.cs b/AutomobilePlant/AutomobilePlantDataBaseImplements/Models/Order.cs index dcfb007..036f72a 100644 --- a/AutomobilePlant/AutomobilePlantDataBaseImplements/Models/Order.cs +++ b/AutomobilePlant/AutomobilePlantDataBaseImplements/Models/Order.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -20,9 +21,12 @@ namespace AutomobilePlantDataBaseImplements.Models [Required] public int ClientId { get; private set; } public string ClientName { get; private set; } = string.Empty; + public int? ImplementerId { get; private set; } + public string? ImplementerName { get; private set; } = string.Empty; public string CarName { get; private set; } = string.Empty; public Client client { get; private set; } public Car car { get; private set; } + public Implementer? implementer { get; private set; } [Required] public int Count { get; private set; } [Required] @@ -60,8 +64,11 @@ namespace AutomobilePlantDataBaseImplements.Models { return; } + ImplementerId = model.ImplementerId; + ImplementerName = model.ImplementerName; Status = model.Status; DateImplement = model.DateImplement; + } public OrderViewModel GetViewModel => new() @@ -69,6 +76,8 @@ namespace AutomobilePlantDataBaseImplements.Models Id = Id, CarId = CarId, ClientId = ClientId, + ImplementerId = ImplementerId, + ImplementerName=ImplementerName, CarName = CarName, ClientName = ClientName, Count = Count, diff --git a/AutomobilePlant/AutomomilePlantFileImplement/DataFileSingleton.cs b/AutomobilePlant/AutomomilePlantFileImplement/DataFileSingleton.cs index be87fbe..8cbbb20 100644 --- a/AutomobilePlant/AutomomilePlantFileImplement/DataFileSingleton.cs +++ b/AutomobilePlant/AutomomilePlantFileImplement/DataFileSingleton.cs @@ -15,10 +15,12 @@ namespace AutomomilePlantFileImplement private readonly string OrderFileName = "Order.xml"; private readonly string CarFileName = "Car.xml"; private readonly string ClientFileName = "Client.xml"; + private readonly string ImplementerFileName = "Implementer.xml"; public List Components { get; private set; } public List Orders { get; private set; } public List Cars { get; private set; } public List Clients { get; private set; } + public List Implementers { get; private set; } public static DataFileSingleton GetInstance() { if (instance == null) @@ -29,10 +31,12 @@ namespace AutomomilePlantFileImplement } public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); - public void SaveCars() => SaveData(Cars, CarFileName, - "Cars", x => x.GetXElement); public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement); + public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, + "Implementers", x => x.GetXElement); + public void SaveCars() => SaveData(Cars, CarFileName, + "Cars", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); private DataFileSingleton() @@ -41,9 +45,10 @@ namespace AutomomilePlantFileImplement Component.Create(x)!)!; Cars = LoadData(CarFileName, "Car", x => Car.Create(x)!)!; - Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; Clients = LoadData(ClientFileName, "Clients", x => Client.Create(x)!)!; + Implementers = LoadData(ImplementerFileName, "Implementers", x => + Implementer.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; } private static List? LoadData(string filename, string xmlNodeName, diff --git a/AutomobilePlant/AutomomilePlantFileImplement/Implements/ImplementerStorage.cs b/AutomobilePlant/AutomomilePlantFileImplement/Implements/ImplementerStorage.cs new file mode 100644 index 0000000..9bfed42 --- /dev/null +++ b/AutomobilePlant/AutomomilePlantFileImplement/Implements/ImplementerStorage.cs @@ -0,0 +1,90 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.SearchModel; +using AutomobilePlantContracts.StoragesContracts; +using AutomobilePlantContracts.ViewModel; +using AutomomilePlantFileImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutomomilePlantFileImplement.Implements +{ + public class ImplementerStorage : IImplementerStorage + { + private readonly DataFileSingleton source; + public ImplementerStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Implementers + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ImplementerSearchModel + model) + { + if (string.IsNullOrEmpty(model.ImplementerFIO) && string.IsNullOrEmpty(model.Password)) + { + return new(); + } + return source.Implementers + .Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO) || x.Password.Contains(model.Password)) + .Select(x => x.GetViewModel) + .ToList(); + } + 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 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.SaveImplementers(); + 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.SaveImplementers(); + 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.SaveImplementers(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/AutomobilePlant/AutomomilePlantFileImplement/Implements/OrderStorage.cs b/AutomobilePlant/AutomomilePlantFileImplement/Implements/OrderStorage.cs index c093a8f..4756608 100644 --- a/AutomobilePlant/AutomomilePlantFileImplement/Implements/OrderStorage.cs +++ b/AutomobilePlant/AutomomilePlantFileImplement/Implements/OrderStorage.cs @@ -45,7 +45,7 @@ namespace AutomomilePlantFileImplement.Implements public List GetFilteredList(OrderSearchModel model) { - if (model is null) + if (!model.Id.HasValue) { return new(); } @@ -57,7 +57,7 @@ namespace AutomomilePlantFileImplement.Implements .ToList(); } return source.Orders - .Where(x => x.DateCreate > model.DateFrom && x.DateCreate < model.DateTo) + .Where(x => x.Id == model.Id && x.DateCreate > model.DateFrom && x.DateCreate < model.DateTo) .Select(x => x.GetViewModel) .ToList(); } @@ -83,6 +83,8 @@ namespace AutomomilePlantFileImplement.Implements return newOrder.GetViewModel; } + + public OrderViewModel? Update(OrderBindingModel model) { var order = source.Orders.FirstOrDefault(x => x.Id == diff --git a/AutomobilePlant/AutomomilePlantFileImplement/Models/Implementer.cs b/AutomobilePlant/AutomomilePlantFileImplement/Models/Implementer.cs new file mode 100644 index 0000000..8640bca --- /dev/null +++ b/AutomobilePlant/AutomomilePlantFileImplement/Models/Implementer.cs @@ -0,0 +1,77 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.ViewModel; +using AutomobilePlantDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace AutomomilePlantFileImplement.Models +{ + public class Implementer : IImplementerModel + { + public int Id { get; private set; } + public string ImplementerFIO { get; private set; } = string.Empty; + public int WorkExperience { get; set; } + public int Qualification { get; set; } + public string Password { get; private set; } = string.Empty; + public static Implementer? Create(ImplementerBindingModel model) + { + if (model == null) + { + return null; + } + return new Implementer() + { + Id = model.Id, + ImplementerFIO = model.ImplementerFIO, + WorkExperience = model.WorkExperience, + Qualification = model.Qualification, + Password = model.Password, + }; + } + public static Implementer? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Implementer() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ImplementerFIO = element.Element("ImplementerFIO")!.Value, + WorkExperience = Convert.ToInt32(element.Attribute("WorkExperience")!.Value), + Qualification = Convert.ToInt32(element.Attribute("Qualification")!.Value), + Password = element.Element("Password")!.Value, + }; + } + public void Update(ImplementerBindingModel model) + { + if (model == null) + { + return; + } + ImplementerFIO = model.ImplementerFIO; + WorkExperience = model.WorkExperience; + Qualification = model.Qualification; + Password = model.Password; + } + public ImplementerViewModel GetViewModel => new() + { + Id = Id, + ImplementerFIO = ImplementerFIO, + WorkExperience = WorkExperience, + Qualification=Qualification, + Password = Password, + }; + public XElement GetXElement => new("Implementer", + new XAttribute("Id", Id), + new XElement("ImplementerFIO", ImplementerFIO), + new XElement("WorkExperience", WorkExperience), + new XElement("Qualification", Qualification), + new XElement("Password", Password) + ); + } +} diff --git a/AutomobilePlant/AutomomilePlantFileImplement/Models/Order.cs b/AutomobilePlant/AutomomilePlantFileImplement/Models/Order.cs index 716d9fd..d26d9c9 100644 --- a/AutomobilePlant/AutomomilePlantFileImplement/Models/Order.cs +++ b/AutomobilePlant/AutomomilePlantFileImplement/Models/Order.cs @@ -17,7 +17,8 @@ namespace AutomomilePlantFileImplement.Models public int ClientId { get; private set; } public string ClientName { get; private set; } = string.Empty; public string CarName { get; private set; } = string.Empty; - + public int? ImplementerId { get; private set; } + public string? ImplementerName { get; private set; } = string.Empty; public int Count { get; private set; } public double Sum { get; private set; } @@ -40,6 +41,8 @@ namespace AutomomilePlantFileImplement.Models CarId = model.CarId, CarName = model.CarName, Count = model.Count, + ImplementerName = model.ImplementerName, + ImplementerId = model.ImplementerId, Sum = model.Sum, Status = model.Status, DateCreate = model.DateCreate, @@ -58,7 +61,11 @@ namespace AutomomilePlantFileImplement.Models Id = Convert.ToInt32(element.Attribute("Id")!.Value), CarId = Convert.ToInt32(element.Element("CarId")!.Value), CarName= element.Element("CarName")!.Value, - Count= Convert.ToInt32(element.Element("Count")!.Value), + ClientId = Convert.ToInt32(element.Element("ClientId")!.Value), + ClientName = element.Element("ClientName")!.Value, + ImplementerId = Convert.ToInt32(element.Element("ImplementerId")!.Value), + ImplementerName = element.Element("ImplementerName")!.Value, + Count = Convert.ToInt32(element.Element("Count")!.Value), Sum= Convert.ToDouble(element.Element("Sum")!.Value), Status= (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value), DateCreate=DateTime.Parse(element.Element("DateCreate")!.Value), @@ -81,6 +88,10 @@ namespace AutomomilePlantFileImplement.Models Id = Id, CarId = CarId, CarName = CarName, + ClientId = ClientId, + ClientName = ClientName, + ImplementerId = ImplementerId, + ImplementerName = ImplementerName, Count = Count, Sum = Sum, Status = Status, diff --git a/AutomobilePlant/AutoplantRestApi/Controllers/ImplementerController.cs b/AutomobilePlant/AutoplantRestApi/Controllers/ImplementerController.cs new file mode 100644 index 0000000..413de8b --- /dev/null +++ b/AutomobilePlant/AutoplantRestApi/Controllers/ImplementerController.cs @@ -0,0 +1,107 @@ +using AutomobilePlantContracts.BindingModels; +using AutomobilePlantContracts.BusinessLogicsContracts; +using AutomobilePlantContracts.SearchModel; +using AutomobilePlantContracts.ViewModel; +using AutomobilePlantDataModels.Enums; +using Microsoft.AspNetCore.Mvc; + +namespace AutoplantRestApi.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class ImplementerController : Controller + { + private readonly ILogger _logger; + + private readonly IOrderLogic _order; + + private readonly IImplementerLogic _logic; + + public ImplementerController(IOrderLogic order, IImplementerLogic logic, ILogger logger) + { + _logger = logger; + _order = order; + _logic = logic; + } + + [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? GetNewOrders() + { + 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, "Ошибка перевода заказа с №{Id} в работу", model.Id); + throw; + } + } + + [HttpPost] + public void FinishOrder(OrderBindingModel model) + { + try + { + _order.FinishOrder(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка отметки о готовности заказа с №{Id}", model.Id); + throw; + } + } + } +}