From 24305408dc9e8cc9662e7ea79108ef71885dda32 Mon Sep 17 00:00:00 2001 From: prodigygirl Date: Sun, 9 Apr 2023 18:55:27 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=BB=D0=B0=D1=81=D1=81=D1=8B=20=D0=B8?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D0=B0=D1=86=D0=B8=D0=B8=20=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D1=8B=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=D0=B5=D0=BB=D0=B5=D0=B9=20=D0=B8=20=D0=B4=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0=20OrderLogic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OrderLogic.cs | 41 +++-- .../WorkModeling.cs | 146 ++++++++++++++++++ .../BusinessLogicsContarcts/IOrderLogic.cs | 1 + .../BusinessLogicsContarcts/IWorkProcess.cs | 10 ++ 4 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 FurnitureAssembly/FurnitureAssemblyBusinessLogic/WorkModeling.cs create mode 100644 FurnitureAssembly/FurnitureAssemblyContracts/BusinessLogicsContarcts/IWorkProcess.cs diff --git a/FurnitureAssembly/FurnitureAssemblyBusinessLogic/OrderLogic.cs b/FurnitureAssembly/FurnitureAssemblyBusinessLogic/OrderLogic.cs index 9bd343e..517595a 100644 --- a/FurnitureAssembly/FurnitureAssemblyBusinessLogic/OrderLogic.cs +++ b/FurnitureAssembly/FurnitureAssemblyBusinessLogic/OrderLogic.cs @@ -55,11 +55,12 @@ namespace FurnitureAssemblyBusinessLogic public bool TakeOrderInWork(OrderBindingModel model) { - model = Find(model); - if (model == null) + var modelNew = ReadElement(new OrderSearchModel { Id = model.Id }); // в связи с обновлением контракта, предыдущий метод не нужен + if (modelNew == null) { return false; } + model.Status = modelNew.Status; if (!ChangeStatus(model, OrderStatus.Выполняется)) { _logger.LogWarning("Order's status is wrong"); @@ -71,32 +72,37 @@ namespace FurnitureAssemblyBusinessLogic public bool FinishOrder(OrderBindingModel model) { - model = Find(model); - if (model == null) { + var modelNew = ReadElement(new OrderSearchModel { Id = model.Id}); // в связи с обновлением контракта, предыдущий метод не нужен + if (modelNew == null) { return false; } + model.Status = modelNew.Status; if (!ChangeStatus(model, OrderStatus.Готов)) { _logger.LogWarning("Order's status is wrong"); return false; } + model.DateImplement = DateTime.Now; _orderStorage.Update(model); return true; } public bool DeliveryOrder(OrderBindingModel model) { - model = Find(model); - if (model == null) + var modelNew = ReadElement(new OrderSearchModel { Id = model.Id }); // в связи с обновлением контракта, предыдущий метод не нужен + if (modelNew == null) { return false; } + model.Status = modelNew.Status; + model.ImplementerId = modelNew.ImplementerId; + model.DateImplement = modelNew.DateImplement; if (!ChangeStatus(model, OrderStatus.Выдан)) { _logger.LogWarning("Order's status is wrong"); return false; } - model.DateImplement = DateTime.Now; + _orderStorage.Update(model); return true; } @@ -143,20 +149,21 @@ namespace FurnitureAssemblyBusinessLogic model.Id, model.Status, model.DateCreate, model.FurnitureId, model.Count, model.Sum); } - private OrderBindingModel? Find(OrderBindingModel model) + public OrderViewModel? ReadElement(OrderSearchModel? model) { - var modelView = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); - if (modelView == null) + if (model == null) { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. Status: {Status}. ImplementerId: {ImplementerId} Id:{ Id}", model.Status, model.ImplementerId, model.Id); + var element = _orderStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); return null; } - model.FurnitureId = modelView.FurnitureId; - model.DateCreate = modelView.DateCreate; - model.Count = modelView.Count; - model.Sum = modelView.Sum; - model.FurnitureId = model.FurnitureId; - model.Status = modelView.Status; - return model; + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; } } } diff --git a/FurnitureAssembly/FurnitureAssemblyBusinessLogic/WorkModeling.cs b/FurnitureAssembly/FurnitureAssemblyBusinessLogic/WorkModeling.cs new file mode 100644 index 0000000..b8b3f3f --- /dev/null +++ b/FurnitureAssembly/FurnitureAssemblyBusinessLogic/WorkModeling.cs @@ -0,0 +1,146 @@ +using FurnitureAssemblyContracts.BindingModels; +using FurnitureAssemblyContracts.BusinessLogicsContarcts; +using FurnitureAssemblyContracts.SearchModels; +using FurnitureAssemblyContracts.ViewModels; +using FurnitureAssemblyDataModels.Enums; +using Microsoft.Extensions.Logging; + +namespace FurnitureAssemblyBusinessLogic +{ + 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, + ImplementerId = implementer.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, + ImplementerId = implementer.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/FurnitureAssembly/FurnitureAssemblyContracts/BusinessLogicsContarcts/IOrderLogic.cs b/FurnitureAssembly/FurnitureAssemblyContracts/BusinessLogicsContarcts/IOrderLogic.cs index 0619a27..20960d1 100644 --- a/FurnitureAssembly/FurnitureAssemblyContracts/BusinessLogicsContarcts/IOrderLogic.cs +++ b/FurnitureAssembly/FurnitureAssemblyContracts/BusinessLogicsContarcts/IOrderLogic.cs @@ -11,6 +11,7 @@ namespace FurnitureAssemblyContracts.BusinessLogicsContarcts { public interface IOrderLogic { + OrderViewModel? ReadElement(OrderSearchModel? model); List? ReadList(OrderSearchModel? model); bool CreateOrder(OrderBindingModel model); bool TakeOrderInWork(OrderBindingModel model); diff --git a/FurnitureAssembly/FurnitureAssemblyContracts/BusinessLogicsContarcts/IWorkProcess.cs b/FurnitureAssembly/FurnitureAssemblyContracts/BusinessLogicsContarcts/IWorkProcess.cs new file mode 100644 index 0000000..2ac2de0 --- /dev/null +++ b/FurnitureAssembly/FurnitureAssemblyContracts/BusinessLogicsContarcts/IWorkProcess.cs @@ -0,0 +1,10 @@ +namespace FurnitureAssemblyContracts.BusinessLogicsContarcts +{ + public interface IWorkProcess + { + /// + /// Запуск работ + /// + void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic); + } +}