176 lines
5.0 KiB
C#
Raw Normal View History

2024-04-22 22:29:10 +04:00
using CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.BusinessLogicsContracts;
using CarRepairShopContracts.SearchModels;
using CarRepairShopContracts.ViewModels;
using CarRepairShopDataModels.Enums;
using Microsoft.Extensions.Logging;
namespace CarRepairShopBusinessLogic.BusinessLogics
{
public class WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
2024-05-08 14:58:03 +04:00
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
2024-04-22 22:29:10 +04:00
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if (implementers == null)
{
_logger.LogWarning("DoWork. Implementers is null");
return;
}
2024-05-08 14:58:03 +04:00
var deliveredOrders = _orderLogic.ReadList(new OrderSearchModel
2024-04-22 22:29:10 +04:00
{
2024-05-08 14:58:03 +04:00
Status = OrderStatus.Выдан
2024-04-22 22:29:10 +04:00
});
2024-05-08 14:58:03 +04:00
var allOrders = _orderLogic.ReadList(null);
if (deliveredOrders == null || allOrders == null || deliveredOrders.Count == allOrders.Count)
2024-04-22 22:29:10 +04:00
{
_logger.LogWarning("DoWork. Orders is null or empty");
return;
}
2024-05-08 14:58:03 +04:00
deliveredOrders.ForEach(x => allOrders.Remove(x));
_logger.LogDebug("DoWork for {Count} orders", allOrders.Count);
2024-04-22 22:29:10 +04:00
foreach (var implementer in implementers)
{
2024-05-08 14:58:03 +04:00
Task.Run(() => WorkerWorkAsync(implementer, allOrders));
2024-04-22 22:29:10 +04:00
}
}
private async Task WorkerWorkAsync(ImplementerViewModel implementer,
List<OrderViewModel> orders)
{
if (_orderLogic == null || implementer == null)
{
return;
}
2024-05-08 14:58:03 +04:00
await DeliverWaitingOrder(implementer);
2024-04-22 22:29:10 +04:00
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);
2024-04-24 16:05:04 +04:00
_orderLogic.TakeOrderInWork(new OrderBindingModel
2024-04-22 22:29:10 +04:00
{
Id = order.Id,
ImplementerId = implementer.Id
});
2024-04-24 16:05:04 +04:00
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
2024-04-22 22:29:10 +04:00
_logger.LogDebug("DoWork. Worker {Id} finish order { Order}", implementer.Id, order.Id);
2024-04-24 16:05:04 +04:00
_orderLogic.FinishOrder(new OrderBindingModel
2024-04-22 22:29:10 +04:00
{
Id = order.Id
});
2024-05-08 14:58:03 +04:00
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = order.Id
});
2024-04-24 16:05:04 +04:00
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
2024-04-22 22:29:10 +04:00
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
});
}
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;
}
2024-04-24 16:05:04 +04:00
_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);
2024-04-22 22:29:10 +04:00
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = runOrder.Id
});
2024-05-08 14:58:03 +04:00
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = runOrder.Id
});
2024-04-22 22:29:10 +04:00
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;
}
}
2024-05-08 14:58:03 +04:00
/// Обрабатываем заказ, которые в ожидании (вдруг место освободилось)
private async Task DeliverWaitingOrder(ImplementerViewModel implementer)
{
if (_orderLogic == null || implementer == null)
{
return;
}
var waitingOrders = await Task.Run(() => _orderLogic.ReadList(new OrderSearchModel
{
ImplementerId = implementer.Id,
Status = OrderStatus.Ожидает
}));
if (waitingOrders == null || waitingOrders.Count == 0)
{
return;
}
_logger.LogInformation("DeliverWaitingOrder. Find some waitig order for implementer:{id}.Count:{count}", implementer.Id, waitingOrders.Count);
foreach (var waitingOrder in waitingOrders)
{
try
{
_logger.LogInformation("DeliverWaitingOrder. Trying to deliver order id:{id}", waitingOrder.Id);
var res = _orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = waitingOrder.Id
});
}
catch (ArgumentException ex)
{
_logger.LogWarning(ex, "DeliverWaitingOrder. Fault");
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try deliver order");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
}
2024-04-22 22:29:10 +04:00
}
}