139 lines
5.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DressAtelierContracts.BindingModels;
using DressAtelierContracts.BusinessLogicContracts;
using DressAtelierContracts.SearchModels;
using DressAtelierContracts.ViewModels;
using DressAtelierDataModels.Enums;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace DressAtelierBusinessLogic.BusinessLogic
{
public class WorkImitation : IWorkImitation
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkImitation(ILogger<WorkImitation> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
public void DoWork(IEmployeeLogic employeeLogic,IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var employees = employeeLogic.ReadList(null);
if(employees == null)
{
_logger.LogWarning("DoWork. List of employees is null");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel
{
Status = OrderStatus.Accepted
});
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 employee in employees)
{
Task.Run(() => EmployeeWorkAsync(employee, orders));
}
}
private async Task EmployeeWorkAsync(EmployeeViewModel employee, List<OrderViewModel> orders)
{
if(_orderLogic == null || employee == null)
{
return;
}
await MoveOrderInWork(employee);
await Task.Run(() =>
{
foreach (var order in orders)
{
try
{
_logger.LogDebug("DoWork. Employee {ID} is trying to get an order {Order}", employee.ID, order.ID);
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
ID = order.ID,
EmployeeID = employee.ID,
});
Thread.Sleep(employee.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Employee {ID} finished order {Order}", employee.ID, order.ID);
_orderLogic.ReadyOrder(new OrderBindingModel
{
ID = order.ID
});
Thread.Sleep(employee.Qualification * _rnd.Next(10, 100));
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Attempt to get work error.");
}
catch (Exception ex)
{
_logger.LogError(ex, "In process of doing work error");
throw;
}
}
});
}
private async Task MoveOrderInWork(EmployeeViewModel employee)
{
if (_orderLogic == null || employee == null) { return; }
try
{
var runOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
EmployeeID = employee.ID,
Status = OrderStatus.InProcess
}));
if (runOrder == null) { return; }
_logger.LogDebug("DoWork. Employee {ID} back to order {Order}", employee.ID, runOrder.ID);
// доделываем работу
Thread.Sleep(employee.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
_logger.LogDebug("DoWork. Employee {ID} finish order {Order}", employee.ID, runOrder.ID);
_orderLogic.ReadyOrder(new OrderBindingModel
{
ID = runOrder.ID
});
// отдыхаем
Thread.Sleep(employee.Qualification * _rnd.Next(10, 100));
}
// заказа может не быть, просто игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Attempt to get work error.");
}
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации
catch (Exception ex)
{
_logger.LogError(ex, "In process of doing work error");
throw;
}
}
}
}