ПИбд-21, Лёвушкина Анна, лаб6 сложная #21

Closed
AnnaLioness wants to merge 6 commits from лаб6_сложная into лаб5_сложная
3 changed files with 215 additions and 127 deletions
Showing only changes of commit 98967a8537 - Show all commits

View File

@ -85,12 +85,18 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
_logger.LogWarning("Read operation failed"); _logger.LogWarning("Read operation failed");
return false; return false;
} }
if (element.Status != status - 1) if (element.Status != status - 1 && element.Status != OrderStatus.Ожидание)
{ {
_logger.LogWarning("Status change operation failed"); _logger.LogWarning("Status change operation failed");
throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный"); throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный");
} }
if (status == OrderStatus.Готов) if (element.ImplementerId.HasValue)
model.ImplementerId = element.ImplementerId;
if (model.DocumentId == 0)
model.DocumentId = element.DocumentId;
if (model.Count == 0)
model.Count = element.Count;
if (status == OrderStatus.Выдан)
{ {
var document = _documentStorage.GetElement(new DocumentSearchModel() { Id = model.DocumentId }); var document = _documentStorage.GetElement(new DocumentSearchModel() { Id = model.DocumentId });
if (document == null) if (document == null)
@ -102,6 +108,9 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
if (!CheckThenSupplyMany(document, model.Count)) if (!CheckThenSupplyMany(document, model.Count))
{ {
_logger.LogWarning("Status change operation failed. Shop supply error."); _logger.LogWarning("Status change operation failed. Shop supply error.");
model.Status = OrderStatus.Ожидание;
if (_orderStorage.Update(model) == null)
_logger.LogWarning("Update operation failed");
return false; return false;
} }
} }

View File

@ -17,11 +17,13 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly Random _rnd; private readonly Random _rnd;
private IOrderLogic? _orderLogic; private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> logger) public WorkModeling(ILogger<WorkModeling> logger)
{ {
_logger = logger; _logger = logger;
_rnd = new Random(1000); _rnd = new Random(1000);
} }
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic) public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{ {
_orderLogic = orderLogic; _orderLogic = orderLogic;
@ -31,37 +33,52 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
_logger.LogWarning("DoWork. Implementers is null"); _logger.LogWarning("DoWork. Implementers is null");
return; return;
} }
var orders = _orderLogic.ReadList(new OrderSearchModel
var orders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Принят });
if (orders == null)
{ {
Status = OrderStatus.Принят _logger.LogWarning("DoWork. Orders is null");
});
if (orders == null || orders.Count == 0)
{
_logger.LogWarning("DoWork. Orders is null or empty");
return; return;
} }
orders.AddRange(_orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Выполняется }) ?? new());
orders.AddRange(_orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Ожидание }) ?? new());
if (orders.Count == 0)
{
_logger.LogWarning("DoWork. Orders is empty");
return;
}
_logger.LogDebug("DoWork for {Count} orders", orders.Count); _logger.LogDebug("DoWork for {Count} orders", orders.Count);
foreach (var implementer in implementers) foreach (var implementer in implementers)
{ {
Task.Run(() => WorkerWorkAsync(implementer, orders)); Task.Run(() => WorkerWorkAsync(implementer, orders));
} }
} }
/// <summary>
/// Иммитация работы исполнителя /// Иммитация работы исполнителя
private async Task WorkerWorkAsync(ImplementerViewModel implementer, /// </summary>
List<OrderViewModel> orders) /// <param name="implementer"></param>
/// <param name="orders"></param>
private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel> orders)
{ {
if (_orderLogic == null || implementer == null) if (_orderLogic == null || implementer == null)
{ {
return; return;
} }
await RunWaitingOrder(implementer);
await RunOrderInWork(implementer); await RunOrderInWork(implementer);
await Task.Run(() => await Task.Run(() =>
{ {
foreach (var order in orders) foreach (var order in orders)
{ {
try try
{ {
_logger.LogDebug("DoWork. Worker {Id} try get order { Order}", implementer.Id, order.Id); _logger.LogDebug("DoWork. Worker {Id} try get order {Order}", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя // пытаемся назначить заказ на исполнителя
_orderLogic.TakeOrderInWork(new OrderBindingModel _orderLogic.TakeOrderInWork(new OrderBindingModel
{ {
@ -70,12 +87,17 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
}); });
// делаем работу // делаем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count); Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order { Order}", implementer.Id, order.Id); _logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
_orderLogic.FinishOrder(new OrderBindingModel _orderLogic.FinishOrder(new OrderBindingModel
{ {
Id = order.Id Id = order.Id
}); });
// доставляем
_logger.LogDebug("DoWork. Worker {Id} delivery order {Order}", implementer.Id, order.Id);
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = order.Id
});
} }
// кто-то мог уже перехватить заказ, игнорируем ошибку // кто-то мог уже перехватить заказ, игнорируем ошибку
catch (InvalidOperationException ex) catch (InvalidOperationException ex)
@ -93,7 +115,12 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
} }
}); });
} }
/// <summary>
/// Ищем заказ, которые уже в работе (вдруг исполнителя прервали) /// Ищем заказ, которые уже в работе (вдруг исполнителя прервали)
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
private async Task RunOrderInWork(ImplementerViewModel implementer) private async Task RunOrderInWork(ImplementerViewModel implementer)
{ {
if (_orderLogic == null || implementer == null) if (_orderLogic == null || implementer == null)
@ -102,8 +129,7 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
} }
try try
{ {
var runOrder = await Task.Run(() => _orderLogic.ReadElement(new var runOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
OrderSearchModel
{ {
ImplementerId = implementer.Id, ImplementerId = implementer.Id,
Status = OrderStatus.Выполняется Status = OrderStatus.Выполняется
@ -112,16 +138,68 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
{ {
return; return;
} }
_logger.LogDebug("DoWork. Worker {Id} back to order {Order}",
implementer.Id, runOrder.Id); _logger.LogDebug("DoWork. Worker {Id} back to order {Order}", implementer.Id, runOrder.Id);
// доделываем работу // доделываем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count); Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", _logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, runOrder.Id);
implementer.Id, runOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel _orderLogic.FinishOrder(new OrderBindingModel
{ {
Id = runOrder.Id Id = runOrder.Id
}); });
// доставляем
_logger.LogDebug("DoWork. Worker {Id} delivery order {Order}", implementer.Id, runOrder.Id);
_orderLogic.DeliveryOrder(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;
}
}
/// <summary>
/// Ищем заказ, которые ждут выдачи (вдруг место освободилось)
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
private async Task RunWaitingOrder(ImplementerViewModel implementer)
{
if (_orderLogic == null || implementer == null)
{
return;
}
try
{
var order = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = implementer.Id,
Status = OrderStatus.Ожидание
}));
if (order == null)
{
return;
}
// доставляем
_logger.LogDebug("DoWork. Worker {Id} delivery order {Order}", implementer.Id, order.Id);
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = order.Id
});
// отдыхаем // отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100)); Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
} }

View File

@ -12,6 +12,7 @@ namespace AbstractLawFirmDataModels.Enums
Принят = 0, Принят = 0,
Выполняется = 1, Выполняется = 1,
Готов = 2, Готов = 2,
Выдан = 3 Выдан = 3,
Ожидание = 4
} }
} }