From 8b09ebcbaab7bc21f5c85442244262c7ba591f24 Mon Sep 17 00:00:00 2001 From: prodigygirl Date: Thu, 20 Apr 2023 21:15:57 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=B0=D0=BB=D1=8F=D0=BA=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BA=D0=B0=20=D1=82=D1=83=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OrderLogic.cs | 21 +++- .../WorkModeling.cs | 97 ++++++++++++++++++- .../Enums/OrderStatus.cs | 3 +- 3 files changed, 112 insertions(+), 9 deletions(-) diff --git a/FurnitureAssembly/FurnitureAssemblyBusinessLogic/OrderLogic.cs b/FurnitureAssembly/FurnitureAssemblyBusinessLogic/OrderLogic.cs index 853580e..c7bb230 100644 --- a/FurnitureAssembly/FurnitureAssemblyBusinessLogic/OrderLogic.cs +++ b/FurnitureAssembly/FurnitureAssemblyBusinessLogic/OrderLogic.cs @@ -28,7 +28,7 @@ namespace FurnitureAssemblyBusinessLogic private bool ChangeStatus(OrderBindingModel model, OrderStatus orderStatus) { - if (model.Status + 1 != orderStatus) + if (model.Status + 1 != orderStatus && !(model.Status == OrderStatus.Ожидание && orderStatus == OrderStatus.Готов) && !(model.Status == OrderStatus.Выполняется && orderStatus == OrderStatus.Ожидание)) { return false; } @@ -62,6 +62,12 @@ namespace FurnitureAssemblyBusinessLogic { return false; } + _logger.LogWarning($""); + if (modelNew.ImplementerId.HasValue) + { + _logger.LogWarning($"Order {model.Id} is already in Work"); + throw new InvalidOperationException($"Order {model.Id} is already in Work"); + } model.Status = modelNew.Status; if (!ChangeStatus(model, OrderStatus.Выполняется)) { @@ -78,13 +84,20 @@ namespace FurnitureAssemblyBusinessLogic if (modelNew == null) { return false; } - if (!_shopLogic.AddFurnituresAtShops(new FurnitureBindingModel() { Id = model.FurnitureId }, model.Count)) + model.ImplementerId = modelNew.ImplementerId; + model.Status = modelNew.Status; + if (!_shopLogic.AddFurnituresAtShops(new FurnitureBindingModel() { Id = modelNew.FurnitureId }, modelNew.Count)) { + if (!ChangeStatus(model, OrderStatus.Ожидание)) + { + _logger.LogWarning($"Order's status {model.Status} is wrong"); + return false; + } + _orderStorage.Update(model); _logger.LogWarning("There are not empty places at shops. Replenishment is impossible"); return false; } - model.Status = modelNew.Status; - model.ImplementerId = modelNew.ImplementerId; + if (!ChangeStatus(model, OrderStatus.Готов)) { _logger.LogWarning("Order's status is wrong"); diff --git a/FurnitureAssembly/FurnitureAssemblyBusinessLogic/WorkModeling.cs b/FurnitureAssembly/FurnitureAssemblyBusinessLogic/WorkModeling.cs index 364f820..069f16b 100644 --- a/FurnitureAssembly/FurnitureAssemblyBusinessLogic/WorkModeling.cs +++ b/FurnitureAssembly/FurnitureAssemblyBusinessLogic/WorkModeling.cs @@ -31,6 +31,20 @@ namespace FurnitureAssemblyBusinessLogic { Status = OrderStatus.Принят }); + var ordersInWorking = _orderLogic.ReadList(new OrderSearchModel + { + Status = OrderStatus.Выполняется + }); + var ordersInWaiting = _orderLogic.ReadList(new OrderSearchModel + { + Status = OrderStatus.Ожидание + }); + // могут остаться заказы в этих статусах, поэтому следует их тоже пустить в работу + if (ordersInWorking != null) + orders?.AddRange(ordersInWorking); + if (ordersInWaiting != null) + orders?.AddRange(ordersInWaiting); + if (orders == null || orders.Count == 0) { _logger.LogWarning("DoWork. Orders is null or empty"); @@ -53,10 +67,44 @@ namespace FurnitureAssemblyBusinessLogic { return; } + // Тут пока комментарий. Итак. По заданию требуется: один заказ "Ожидание" -> все заказы "Выполняется" -> все заказы "Принят", + // но в этом случае мы никогда можем не выполнить ожидающиеся... + + // Сейчас логика такая: все заказы "Ожидание" -> один заказ "Выполняется" -> все заказы "Принят". Таким образом, мы потенциально можем выполнить все находящиеся в ожидании, + // потом только взять один заказ из выполняющихся и перейти к новым + //await RunOrderInWaiting(implementer); + await Task.Run(() => + { + foreach (var order in orders.Where(x => x.Status == OrderStatus.Ожидание && x.ImplementerId == implementer.Id)) + { + try + { + _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; + } + + } + }); + await RunOrderInWork(implementer); await Task.Run(() => { - foreach (var order in orders) + foreach (var order in orders.Where(x => x.Status == OrderStatus.Принят)) { try { @@ -72,9 +120,9 @@ namespace FurnitureAssemblyBusinessLogic 1000) * order.Count); _logger.LogDebug("DoWork. Worker {Id} finish order{ Order} ", implementer.Id, order.Id); _orderLogic.FinishOrder(new OrderBindingModel - { - Id = order.Id - }); + { + Id = order.Id + }); // отдыхаем Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100)); } @@ -140,5 +188,46 @@ namespace FurnitureAssemblyBusinessLogic throw; } } + /// + /// Ищем заказ, которые находятся в ожидании + /// + /// + /// + private async Task RunOrderInWaiting(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; + } + _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/FurnitureAssembly/FurnitureAssemblyDataModels/Enums/OrderStatus.cs b/FurnitureAssembly/FurnitureAssemblyDataModels/Enums/OrderStatus.cs index 0f80752..b1c607a 100644 --- a/FurnitureAssembly/FurnitureAssemblyDataModels/Enums/OrderStatus.cs +++ b/FurnitureAssembly/FurnitureAssemblyDataModels/Enums/OrderStatus.cs @@ -12,6 +12,7 @@ namespace FurnitureAssemblyDataModels.Enums Принят = 0, Выполняется = 1, Готов = 2, - Выдан = 3 + Выдан = 3, + Ожидание = 4 } }