feat(master): обновлена логика статусов нарядов, присвояения значений журнала агента.

This commit is contained in:
Mikhail Trubnikov
2023-11-16 14:24:22 +10:00
parent 6e4035cde1
commit 15d84485dd
3 changed files with 96 additions and 32 deletions

View File

@@ -1,5 +1,4 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using PARR.DAL.Contracts;
using PARR.DAL.Models.Base; using PARR.DAL.Models.Base;
using PARR.DAL.Settings; using PARR.DAL.Settings;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
@@ -22,8 +21,32 @@ namespace PARR.DAL.Models
public Guid ApplicationId { get; set; } public Guid ApplicationId { get; set; }
/// <summary>
/// TemplateDuration в формате ЕСПП
/// </summary>
public required string TemplateDuration { get; set; } public required string TemplateDuration { get; set; }
/// <summary>
/// TemplateDuration в формате TimeSpan
/// </summary>
public TimeSpan? TemplateDurationTimeSpan
{
get
{
try
{
//ЕСПП кривоногие, они почему-то таймспан пишут так "7 00:00:00", а правильно так: "7:00:00:00"
var durationWithTimeSpanFormat = TemplateDuration.Replace(" ", ":");
return TimeSpan.Parse(durationWithTimeSpanFormat);
}
catch
{
return null;
}
}
}
public required string ShortDescription { get; set; } public required string ShortDescription { get; set; }
//public required string FullDescription { get; set; } //public required string FullDescription { get; set; }

View File

@@ -53,7 +53,7 @@ namespace PARR.EsppOrderLoader.Services
StatusCode = (int)orderStatusService.GetOrderStatusByName(esppOrder.Status), StatusCode = (int)orderStatusService.GetOrderStatusByName(esppOrder.Status),
GenerateDate = template == null ? GenerateDate = template == null ?
null null
: CalcGenerationDate(esppOrder.ExpirationDateUTC, template.ApplicationsInWork!.TemplateDuration) : CalcGenerationDate(esppOrder.ExpirationDateUTC, template.ApplicationsInWork!.TemplateDurationTimeSpan)
}; };
if (!await orderService.CreateAsync(newOrder) || !await orderService.CommitAsync()) if (!await orderService.CreateAsync(newOrder) || !await orderService.CommitAsync())
@@ -63,23 +63,29 @@ namespace PARR.EsppOrderLoader.Services
} }
private DateTimeOffset? CalcGenerationDate(DateTimeOffset expirationDateUTC, string templateDuration) private DateTimeOffset? CalcGenerationDate(DateTimeOffset expirationDateUTC, TimeSpan? templateDuration)
{ {
TimeSpan duration; //TimeSpan duration;
try //try
//{
// //ЕСПП кривоногие, они почему-то таймспан пишут так "7 00:00:00", а правильно так: "7:00:00:00"
// var durationWithTimeSpanFormat = templateDuration.Replace(" ", ":");
// duration = TimeSpan.Parse(durationWithTimeSpanFormat);
//}
//catch (Exception e)
//{
// logger.LogError(e, $"Ошибка при конвертации templateDuration в TimeSpan, исходное значение: {templateDuration}");
// return null;
//}
if (templateDuration.HasValue)
return expirationDateUTC.Add(-templateDuration.Value);
else
{ {
//ЕСПП кривоногие, они почему-то таймспан пишут так "7 00:00:00", а правильно так: "7:00:00:00" logger.LogError($"templateDuration = null.");
var durationWithTimeSpanFormat = templateDuration.Replace(" ", ":");
duration = TimeSpan.Parse(durationWithTimeSpanFormat);
}
catch (Exception e)
{
logger.LogError(e, $"Ошибка при конвертации templateDuration в TimeSpan, исходное значение: {templateDuration}");
return null; return null;
} }
return expirationDateUTC.Add(-duration);
} }
} }

View File

@@ -40,15 +40,18 @@ namespace PARR.Master.Services
public async Task ManageOrdersAsync() public async Task ManageOrdersAsync()
{ {
// логика работы описана в документации проекта
logger.LogInformation($"--- Начало поиска нарядов ---"); logger.LogInformation($"--- Начало поиска нарядов ---");
//ищем наряды в статусе 1 и 2, присваиваем им историю работы агента, меняем стаус наряда //ищем наряды в статусе 1 и 2
var ordersToManage = await GetOrdersNewOrWorkStatusesAsync(); var ordersToManage = await GetOrdersNewOrWorkStatusesAsync();
logger.LogInformation($"Ищу наряды со статусом 1 и 2. Найдено нарядов: {ordersToManage.Count()} шт."); logger.LogInformation($"Ищу наряды со статусом 1 и 2. Найдено нарядов: {ordersToManage.Count()} шт.");
foreach (var order in ordersToManage) foreach (var order in ordersToManage)
{ {
//присваиваем им историю работы агента, меняем стаус наряда
logger.LogInformation($"Найден наряд id: {order.Id}, {order.Number}"); logger.LogInformation($"Найден наряд id: {order.Id}, {order.Number}");
await SetHistoryAndUpdateOrderStatus(order); await SetHistoryAndUpdateOrderStatus(order);
} }
@@ -84,49 +87,80 @@ namespace PARR.Master.Services
/// <returns></returns> /// <returns></returns>
private async Task SetHistoryAndUpdateOrderStatus(Order order) private async Task SetHistoryAndUpdateOrderStatus(Order order)
{ {
//TODO: тут тот таймаут? или надо TemplateDuration
var agentHistory = await agentHistoryService.Get() var agentHistory = await agentHistoryService.Get()
.Where(t => .Where(t =>
t.TemplateId == order.TemplateId t.TemplateId == order.TemplateId
&& t.DateCreated > order.GenerateDate!.Value.Add(-orderManageSettings.FindAgentHistoryStartOffset) && t.DateCreated > order.GenerateDate!.Value.Add(-orderManageSettings.FindAgentHistoryStartOffset)
&& t.DateCreated <= order.GenerateDate!.Value.AddSeconds(order.Template!.ApplicationsInWork!.AgentTimeOutSec!.Value) //&& t.DateCreated <= order.GenerateDate!.Value.AddSeconds(order.Template!.ApplicationsInWork!.AgentTimeOutSec!.Value)
&& t.DateCreated <= order.GenerateDate!.Value.Add(order.Template!.ApplicationsInWork!.TemplateDurationTimeSpan!.Value)
&& t.OrderId == null && t.OrderId == null
) )
.OrderBy(t => t.DateCreated)
.ToListAsync(); .ToListAsync();
logger.LogInformation($"Для наряда {order.Id}, {order.Number} надено новых историй агентов: {agentHistory.Count()} шт. Присваиваю истории ИД наряда."); logger.LogInformation($"Для наряда {order.Id}, {order.Number} найдено новых историй агентов: {agentHistory.Count()} шт.");
foreach (var historyItem in agentHistory) foreach (var historyItem in agentHistory)
{
historyItem.OrderId = order.Id; historyItem.OrderId = order.Id;
logger.LogDebug($"Для наряда {order.Id}, {order.Number} добавил истрию агента {historyItem.Id}, {historyItem.HistoryLevelId}");
// если статус агента = завершил работу. то историю после завешения, не записываем, это возможно относится к другому наряду, или нам уже пофиг на неё
if (historyItem.HistoryLevelId == (int)AgentHistoryLevelEnum.End)
{
logger.LogDebug($"Для наряда {order.Id}, {order.Number} прекращаю добавлять историю агента, так как добавлена запись со статусом Стоп");
continue;
}
}
//отбрасываем все записи которые не добавлены этому наряду
agentHistory = agentHistory.Where(t => t.OrderId.HasValue).ToList();
// совмещенный список истории агента по этому наряду
var allHistory = agentHistory;
order.AgentHistories.ToList().ForEach(item => allHistory.Add(item));
allHistory = allHistory.OrderBy(t => t.DateCreated).ToList();
// смотрим историю агента, и тут же меняем статус наряда // смотрим историю агента, и тут же меняем статус наряда
//1 Ищем статус "Агент начал выполнять задание" //1 Ищем статус "Агент начал выполнять задание"
var isAgentStarted = agentHistory.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.Start) || order.AgentHistories.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.Start); var isAgentStarted = allHistory.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.Start);
//2 Ищем статус "Агент завершил выполнение задания" //2 Ищем статус "Агент завершил выполнение задания"
var isAgentEnded = agentHistory.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.End) || order.AgentHistories.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.End); var isAgentEnded = allHistory.Any(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.End);
if (isAgentEnded) if (isAgentEnded)
{ {
order.NextStatusCode = (int)OrderStatusEnum.Complete; order.NextStatusCode = (int)OrderStatusEnum.Complete;
logger.LogInformation($"Для наряда {order.Id}, {order.Number} меню статус на {OrderStatusEnum.Complete}"); logger.LogInformation($"Для наряда {order.Id}, {order.Number} меняю статус на {OrderStatusEnum.Complete}");
} }
if (isAgentStarted && !isAgentEnded && order.StatusCode == (int)OrderStatusEnum.New) if (isAgentStarted && !isAgentEnded && order.StatusCode == (int)OrderStatusEnum.New)
{ {
order.NextStatusCode = (int)OrderStatusEnum.InWork; order.NextStatusCode = (int)OrderStatusEnum.InWork;
logger.LogInformation($"Для наряда {order.Id}, {order.Number} меню статус на {OrderStatusEnum.InWork}"); logger.LogInformation($"Для наряда {order.Id}, {order.Number} меняю статус на {OrderStatusEnum.InWork}");
} }
//TODO: тут подумать про таймаут, по какому таймауту закрывтаь наряд? по таймауту агента, или по TemplateDuration? //закрываем по таймауту. Если есть начало, и нет завершения по АгентТаймаут, то закрываем наряд.
//timeout if (isAgentStarted == true && isAgentEnded == false)
//if(isAgentStarted==false && isAgentEnded == false && ) {
//{ var lastStrartDate = allHistory.Last(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.Start).DateCreated;
// // ставим Выполнен, так как превысил таймаут var timeout = (double)order.Template!.ApplicationsInWork!.AgentTimeOutSec!;
// order.NextStatusCode = (int)OrderStatusEnum.Complete;
// logger.LogInformation($"Для наряда {order.Id}, {order.Number} меню статус на {OrderStatusEnum.Complete}"); if (lastStrartDate.AddSeconds(timeout) <= DateTimeOffset.UtcNow)
//} {
order.NextStatusCode = (int)OrderStatusEnum.Complete;
logger.LogInformation($"Для наряда {order.Id}, {order.Number} меняю статус на {OrderStatusEnum.Complete}, закрываю наряд по таймауту ожидания агента. Время старта агента: {lastStrartDate}, допустимый timeOut: {timeout} сек.");
}
else
{
logger.LogDebug($"Для наряда {order.Id}, {order.Number} оставляю статус прежним, ожидаю завершение работы агента. Время старта агента: {lastStrartDate}, допустимый timeOut: {timeout} сек.");
}
}
//TODO: тут можно подумать, и закрывать наряды, у которых нет истории агента. сейчас мы такие наряды пропускаем, их будет закрывать руками админ.
if (!await orderService.CommitAsync()) if (!await orderService.CommitAsync())
{ {
@@ -173,7 +207,8 @@ namespace PARR.Master.Services
&& t.Template!.ApplicationsInWork!.IsAgent == true && t.Template!.ApplicationsInWork!.IsAgent == true
&& t.GenerateDate.HasValue && t.GenerateDate.HasValue
&& t.Template!.ApplicationsInWork!.AgentTimeOutSec.HasValue && t.Template!.ApplicationsInWork!.AgentTimeOutSec.HasValue
); && string.IsNullOrEmpty(t.Template!.ApplicationsInWork!.TemplateDuration) == false
).OrderBy(t => t.DateCreated);
} }
} }
} }