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
}
}