feat(master): обновлена логика статусов нарядов, присвояения значений журнала агента.
This commit is contained in:
@@ -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; }
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user