diff --git a/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogics/WorkModeling.cs b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogics/WorkModeling.cs new file mode 100644 index 0000000..452a88f --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogics/WorkModeling.cs @@ -0,0 +1,140 @@ +using BlacksmithWorkshopContracts.BindingModels; +using BlacksmithWorkshopContracts.BusinessLogicContracts; +using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.SearchModels; +using BlacksmithWorkshopContracts.ViewModels; +using BlacksmithWorkshopDataModels.Enums; +using Microsoft.Extensions.Logging; + +namespace BlacksmithWorkshopBusinessLogic.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 + }); + // делаем работу + 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 + }); + } + // кто-то мог уже перехватить заказ, игнорируем ошибку + 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 {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/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/OrderBindingModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/OrderBindingModel.cs index 5a551ac..d5b2dce 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/OrderBindingModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/OrderBindingModel.cs @@ -13,6 +13,6 @@ namespace BlacksmithWorkshopContracts.BindingModels public DateTime DateCreate { get; set; } = DateTime.Now; public DateTime? DateImplement { get; set; } public int ClientId { get; set; } - public int ImplementerId { get; set; } + public int? ImplementerId { get; set; } } } \ No newline at end of file diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IWorkProcess.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IWorkProcess.cs new file mode 100644 index 0000000..30f02a4 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IWorkProcess.cs @@ -0,0 +1,12 @@ +using BlacksmithWorkshopContracts.BusinessLogicContracts; + +namespace BlacksmithWorkshopContracts.BusinessLogicsContracts +{ + public interface IWorkProcess + { + /// + /// Запуск работ + /// + void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic); + } +} diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/OrderViewModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/OrderViewModel.cs index ac393fa..8e6e8e3 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/OrderViewModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/OrderViewModel.cs @@ -24,7 +24,7 @@ namespace BlacksmithWorkshopContracts.ViewModels public DateTime? DateImplement { get; set; } [DisplayName("Клиент")] public string ClientFIO { get; set; } = string.Empty; - public int ImplementerId { get; set; } + public int? ImplementerId { get; set; } [DisplayName("Исполнитель")] public string ImplementerFIO { get; set; } = string.Empty; } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDataModels/Models/IOrderModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopDataModels/Models/IOrderModel.cs index dc0fec0..56ae017 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDataModels/Models/IOrderModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDataModels/Models/IOrderModel.cs @@ -11,6 +11,6 @@ namespace BlacksmithWorkshopDataModels.Models OrderStatus Status { get; } DateTime DateCreate { get; } DateTime? DateImplement { get; } - int ImplementerId { get; } + int? ImplementerId { get; } } } \ No newline at end of file diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatebaseImplement/Implements/OrderStorage.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatebaseImplement/Implements/OrderStorage.cs index 4cf493e..1fcfa75 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatebaseImplement/Implements/OrderStorage.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatebaseImplement/Implements/OrderStorage.cs @@ -89,11 +89,16 @@ namespace BlacksmithWorkshopDatabaseImplement.Implements return context.Orders .FirstOrDefault(x => x.Id == model.Id)?.GetViewModel; } - if (model.ImplementerId.HasValue) + if (model.ImplementerId.HasValue && !model.Status.HasValue)//Затем только по исполнителю { return context.Orders .FirstOrDefault(x => x.ImplementerId == model.ImplementerId)?.GetViewModel; } + if (model.ImplementerId.HasValue && model.Status.HasValue)//Затем по исполнителю и статусу + { + return context.Orders + .FirstOrDefault(x => x.ImplementerId == model.ImplementerId && x.Status == model.Status)?.GetViewModel; + } return null; } public OrderViewModel? Insert(OrderBindingModel model) diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatebaseImplement/Models/Order.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatebaseImplement/Models/Order.cs index 2b7ddfe..c217dda 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatebaseImplement/Models/Order.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatebaseImplement/Models/Order.cs @@ -24,8 +24,7 @@ namespace BlacksmithWorkshopDatabaseImplement.Models public int ClientId { get; private set; } [Required] public virtual Client? Client { get; private set; } - [Required] - public int ImplementerId { get; private set; } + public int? ImplementerId { get; private set; } public virtual Implementer? Implementer { get; private set; } public static Order? Create(OrderBindingModel model) { @@ -66,6 +65,10 @@ namespace BlacksmithWorkshopDatabaseImplement.Models return; } Status = model.Status; + if (model.ImplementerId != null) + { + ImplementerId = model.ImplementerId; + } if (model.DateImplement != null) { DateImplement = model.DateImplement; diff --git a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Order.cs b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Order.cs index b7e4192..1e1e0d5 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Order.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Order.cs @@ -17,7 +17,7 @@ namespace BlacksmithWorkshopFileImplement.Models public DateTime? DateImplement { get; private set; } public int ClientId { get; private set; } //TODO - public int ImplementerId => throw new NotImplementedException(); + public int? ImplementerId => throw new NotImplementedException(); public static Order? Create(OrderBindingModel? model) { if (model == null) diff --git a/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Models/Order.cs b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Models/Order.cs index b53582a..4d95925 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Models/Order.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Models/Order.cs @@ -17,7 +17,7 @@ namespace BlacksmithWorkshopListImplement.Models public DateTime? DateImplement { get; private set; } public int ClientId { get; private set; } //TODO - public int ImplementerId => throw new NotImplementedException(); + public int? ImplementerId => throw new NotImplementedException(); public static Order? Create(OrderBindingModel? model) { if (model == null)