Files
parr_api/PARR.EsppOrderManager/EsppOrderManager.cs

193 lines
7.7 KiB
C#
Raw 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 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.EsppApi;
using PARR.EsppApi.Models.Query;
using PARR.EsppOrderManager.Services;
using PARR.EsppOrderManager.Settings;
namespace PARR.EsppOrderManager
{
internal class EsppOrderManager : IEsppOrderManager
{
private readonly MqSettings mqSettings;
private readonly IMqService mqService;
private readonly ILogger<EsppOrderManager> logger;
private readonly ITransformService transformService;
private readonly IOrderService orderService;
private readonly IEsppOrderService esppOrderService;
public EsppOrderManager(
MqSettings mqSettings,
IMqService mqService,
ILogger<EsppOrderManager> logger,
ITransformService transformService,
IOrderService orderService,
IEsppOrderService esppOrderService
)
{
this.mqSettings = mqSettings;
this.mqService = mqService;
this.logger = logger;
this.transformService = transformService;
this.orderService = orderService;
this.esppOrderService = esppOrderService;
}
public async void Start()
{
// логика работы описана в документации
//var isConnected = mqService.InitConsumer(mqSettings, ManageOrder);
//if (!isConnected)
// throw new Exception("Ошибка при подключении к RabbitMq");
//test, and remove async in method name
await ManageOrder("{\"OrderId\":\"77eeccfb-4ca0-443e-8cc7-f6aa9dc774b7\"}");
}
public void Stop()
{
mqService.Dispose();
}
private async Task ManageOrder(string msg)
{
logger.LogDebug($"Получили сообщение: {msg}");
var obj = transformService.GetModelFromJson<OrderManageMq>(msg);
if (obj == null)
return;
var order = await orderService.Get()
.Include(t => t.AgentHistories).ThenInclude(t => t.AgentHistoryLevel)
.Include(t => t.OrderStatus)
.Include(t => t.NextStatus)
.Include(t => t.Template).ThenInclude(t => t!.ApplicationsInWork).ThenInclude(t => t!.Work).ThenInclude(t => t!.Tnk)
.FirstOrDefaultAsync(t => t.Id == obj.OrderId);
if (order == null)
{
logger.LogError($"Не найден наряд с OrderId: {obj.OrderId}");
return;
}
if (order.StatusCode == order.NextStatusCode)
{
logger.LogInformation($"У наряда {order.Id}, {order.Number} статусы равны, ничего не делаем. Статус: {order.OrderStatus!.Description}");
return;
}
if (!order.NextStatusCode.HasValue)
{
logger.LogWarning($"У наряда {order.Id}, {order.Number} не установлено поле {nameof(order.NextStatusCode)}");
return;
}
var resultMsg = GenerateResultMsg(order);
var workDuration = CalcWorkDuration(order);
// Изменям статус наряда в ЕСПП
var result = await esppOrderService.ChangeOrderToEsppAsync(order, resultMsg, workDuration);
if (result)
{
logger.LogInformation($"Статусы наряда {order.Number} в ЕСПП обновлены. Установлен статус: {order.NextStatus!.Description}");
//обновляем статусы в БД
order.StatusCode = order.NextStatusCode.Value;
if (!await orderService.CommitAsync())
{
logger.LogError($"Ошибка при обновлении статуса в БД у наряда: {order.Number}. Не установлен статус {order.NextStatus!.Description}");
}
}
else
logger.LogError($"Ошибка при обновлении статуса наряда {order.Number}. Статус не изменен.");
logger.LogDebug($"Закончил работу с сообщением: {msg}");
}
/// <summary>
/// Генерирует текст поля Решение, в зависимости от статуса наряда и от истории Агента
/// </summary>
/// <param name="order"></param>
/// <returns></returns>
private string GenerateResultMsg(Order order)
{
var agentHistory = order.AgentHistories
.OrderBy(t => t.DateCreated)
.Select(t => $"{t.DateCreated} :: {t.AgentHistoryLevel?.Name} :: {t.Message}");
var baseMsg = order.Template!.ApplicationsInWork!.Solution + "\r\n";
var msgAgent = "Работы выполнены средствами автоматизации. \r\n" +
"Журнал работы: \r\n" +
$"{string.Join("\r\n", agentHistory)}";
var msgAgentEmpty = "Работы должны были выполняться средствами автоматизации. " +
"От средств автоматизации не поступило сообщений. " +
"Работы не выполнены.";
return baseMsg + (agentHistory.Any() ? msgAgent : msgAgentEmpty);
}
/// <summary>
/// Рассчиать трудозатраты
/// </summary>
/// <param name="order"></param>
/// <returns></returns>
private TimeSpan CalcWorkDuration(Order order)
{
var agentHistory = order.AgentHistories
.OrderBy(t => t.DateCreated);
if (!agentHistory.Any())
return GetTnkDurationByScriptDuration(TimeSpan.Zero);
var dateStart = agentHistory.LastOrDefault(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.Start)?.DateCreated;
var dateEnd = agentHistory.LastOrDefault(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.End)?.DateCreated;
if (dateStart.HasValue && dateEnd.HasValue)
{
var duration = dateEnd.Value - dateStart.Value;
logger.LogDebug($"Продолжительность работы скрипта: {duration}");
return GetTnkDurationByScriptDuration(duration);
}
return GetTnkDurationByScriptDuration(TimeSpan.Zero);
}
/// <summary>
/// Получить время для списания ТНК по времени работы скрипта
/// </summary>
/// <param name="scriptDuration"></param>
/// <returns></returns>
private TimeSpan GetTnkDurationByScriptDuration(TimeSpan scriptDuration)
{
// минимальное значение 1 минута
var minDuration = new TimeSpan(0, 1, 0);
if (scriptDuration < minDuration)
{
logger.LogDebug($"Продолжительность меньше минимального, беру минимальное: {minDuration}. {scriptDuration}<{minDuration}");
return minDuration;
}
else
return scriptDuration;
}
}
}