feat(master): логика присвоения истории агента нарядам. Изменение статуса наряда. Отправка в MQ.

This commit is contained in:
Mikhail Trubnikov
2023-11-15 16:34:28 +10:00
parent c4c8b748f0
commit 6e4035cde1
8 changed files with 237 additions and 8 deletions

View File

@@ -0,0 +1,7 @@
namespace PARR.Master.Services
{
internal interface IOrderMasterService
{
Task ManageOrdersAsync();
}
}

View File

@@ -0,0 +1,179 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using PARR.BLL.Domain.Mq;
using PARR.BLL.Services.Interfaces;
using PARR.DAL.Contracts;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces;
using PARR.Master.Settings;
using System.Text.Json;
namespace PARR.Master.Services
{
internal class OrderMasterService : IOrderMasterService
{
private readonly ILogger<OrderMasterService> logger;
private readonly IOrderService orderService;
private readonly IAgentHistoryService agentHistoryService;
private readonly OrderManageSettings orderManageSettings;
private readonly MqSettings mqSettings;
private readonly IMqService mqService;
public OrderMasterService(
ILogger<OrderMasterService> logger,
IOrderService orderService,
IAgentHistoryService agentHistoryService,
OrderManageSettings orderManageSettings,
MqSettings mqSettings,
IMqService mqService
)
{
this.logger = logger;
this.orderService = orderService;
this.agentHistoryService = agentHistoryService;
this.orderManageSettings = orderManageSettings;
this.mqSettings = mqSettings;
this.mqService = mqService;
}
public async Task ManageOrdersAsync()
{
logger.LogInformation($"--- Начало поиска нарядов ---");
//ищем наряды в статусе 1 и 2, присваиваем им историю работы агента, меняем стаус наряда
var ordersToManage = await GetOrdersNewOrWorkStatusesAsync();
logger.LogInformation($"Ищу наряды со статусом 1 и 2. Найдено нарядов: {ordersToManage.Count()} шт.");
foreach (var order in ordersToManage)
{
logger.LogInformation($"Найден наряд id: {order.Id}, {order.Number}");
await SetHistoryAndUpdateOrderStatus(order);
}
//находим наряды где статусы не равны, добавляем их в Rabbit
var ordersWithStatusNotEqual = await GetOrdresWithStatusCodeNotEqualAsync();
var objs = ordersWithStatusNotEqual.Select(t => JsonSerializer.Serialize(new OrderManageMq { OrderId = t.Id }));
logger.LogInformation($"Ищу наряды где статусы не равны. Найдено нарядов: {ordersWithStatusNotEqual.Count()}. Добавляю их в RabbitMQ.");
if (objs.Any())
{
var sendResult = mqService.Send(mqSettings, objs.ToArray());
if (sendResult.IsSuccess)
{
logger.LogInformation($"Наряды переданы в RabbitMQ: {objs.Count()}");
logger.LogDebug($"Список нардов переданных в RabbitMQ: {string.Join(", ", objs)}");
}
else
logger.LogError($"Ошибка при передаче нарядов в Rabbit, неперадынные сообщения: {string.Join(", ", sendResult!.NotSendMessages)}");
}
logger.LogInformation($"=== Конец работы с нарядами=== ");
}
/// <summary>
/// Находит наряды в статусе 1 и 2, присваивает им историю работы агента, меняет стаус наряда
/// </summary>
/// <param name="order"></param>
/// <returns></returns>
private async Task SetHistoryAndUpdateOrderStatus(Order order)
{
//TODO: тут тот таймаут? или надо TemplateDuration
var agentHistory = await agentHistoryService.Get()
.Where(t =>
t.TemplateId == order.TemplateId
&& t.DateCreated > order.GenerateDate!.Value.Add(-orderManageSettings.FindAgentHistoryStartOffset)
&& t.DateCreated <= order.GenerateDate!.Value.AddSeconds(order.Template!.ApplicationsInWork!.AgentTimeOutSec!.Value)
&& t.OrderId == null
)
.ToListAsync();
logger.LogInformation($"Для наряда {order.Id}, {order.Number} надено новых историй агентов: {agentHistory.Count()} шт. Присваиваю истории ИД наряда.");
foreach (var historyItem in agentHistory)
historyItem.OrderId = order.Id;
// смотрим историю агента, и тут же меняем статус наряда
//1 Ищем статус "Агент начал выполнять задание"
var isAgentStarted = agentHistory.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.Start) || order.AgentHistories.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.Start);
//2 Ищем статус "Агент завершил выполнение задания"
var isAgentEnded = agentHistory.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.End) || order.AgentHistories.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.End);
if (isAgentEnded)
{
order.NextStatusCode = (int)OrderStatusEnum.Complete;
logger.LogInformation($"Для наряда {order.Id}, {order.Number} меню статус на {OrderStatusEnum.Complete}");
}
if (isAgentStarted && !isAgentEnded && order.StatusCode == (int)OrderStatusEnum.New)
{
order.NextStatusCode = (int)OrderStatusEnum.InWork;
logger.LogInformation($"Для наряда {order.Id}, {order.Number} меню статус на {OrderStatusEnum.InWork}");
}
//TODO: тут подумать про таймаут, по какому таймауту закрывтаь наряд? по таймауту агента, или по TemplateDuration?
//timeout
//if(isAgentStarted==false && isAgentEnded == false && )
//{
// // ставим Выполнен, так как превысил таймаут
// order.NextStatusCode = (int)OrderStatusEnum.Complete;
// logger.LogInformation($"Для наряда {order.Id}, {order.Number} меню статус на {OrderStatusEnum.Complete}");
//}
if (!await orderService.CommitAsync())
{
logger.LogError($"Ошибка при сохранении НАРЯДА, id: {order.Id}");
}
logger.LogInformation($"Закончил работу с нарядом {order.Id}, {order.Number}");
}
/// <summary>
/// Получить список нарядов, со статусами 1 или 2
/// </summary>
private async Task<List<Order>> GetOrdersNewOrWorkStatusesAsync()
{
return await GetOrdres()
.Where(t => t.StatusCode == (int)OrderStatusEnum.New || t.StatusCode == (int)OrderStatusEnum.InWork)
.ToListAsync();
}
/// <summary>
/// Получить список нарядов, у которых StatusCode!=NextStatusCode
/// </summary>
private async Task<List<Order>> GetOrdresWithStatusCodeNotEqualAsync()
{
return await GetOrdres()
.Where(t => t.NextStatusCode.HasValue && t.NextStatusCode.Value != t.StatusCode)
.ToListAsync();
}
/// <summary>
/// Основной запрос на получения списка нарядов со связями, по базовому условию
/// </summary>
/// <returns></returns>
private IQueryable<Order> GetOrdres()
{
return orderService.Get()
.Include(t => t.Template).ThenInclude(t => t!.ApplicationsInWork)
.Include(t => t.AgentHistories)
.Where(t =>
t.TemplateId.HasValue
&& t.Template!.ApplicationsInWork!.IsAgent == true
&& t.GenerateDate.HasValue
&& t.Template!.ApplicationsInWork!.AgentTimeOutSec.HasValue
);
}
}
}