diff --git a/PARR.DAL/Models/ApplicationsInWork.cs b/PARR.DAL/Models/ApplicationsInWork.cs
index 0ccbc4d2..2796cd7d 100644
--- a/PARR.DAL/Models/ApplicationsInWork.cs
+++ b/PARR.DAL/Models/ApplicationsInWork.cs
@@ -1,5 +1,4 @@
using Microsoft.EntityFrameworkCore;
-using PARR.DAL.Contracts;
using PARR.DAL.Models.Base;
using PARR.DAL.Settings;
using System.ComponentModel.DataAnnotations;
@@ -22,8 +21,32 @@ namespace PARR.DAL.Models
public Guid ApplicationId { get; set; }
+ ///
+ /// TemplateDuration в формате ЕСПП
+ ///
public required string TemplateDuration { get; set; }
+ ///
+ /// TemplateDuration в формате TimeSpan
+ ///
+ 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 FullDescription { get; set; }
diff --git a/PARR.EsppOrderLoader/Services/OrderItemService.cs b/PARR.EsppOrderLoader/Services/OrderItemService.cs
index dd9adb9b..85a4d9aa 100644
--- a/PARR.EsppOrderLoader/Services/OrderItemService.cs
+++ b/PARR.EsppOrderLoader/Services/OrderItemService.cs
@@ -53,7 +53,7 @@ namespace PARR.EsppOrderLoader.Services
StatusCode = (int)orderStatusService.GetOrderStatusByName(esppOrder.Status),
GenerateDate = template == null ?
null
- : CalcGenerationDate(esppOrder.ExpirationDateUTC, template.ApplicationsInWork!.TemplateDuration)
+ : CalcGenerationDate(esppOrder.ExpirationDateUTC, template.ApplicationsInWork!.TemplateDurationTimeSpan)
};
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"
- var durationWithTimeSpanFormat = templateDuration.Replace(" ", ":");
- duration = TimeSpan.Parse(durationWithTimeSpanFormat);
- }
- catch (Exception e)
- {
- logger.LogError(e, $"Ошибка при конвертации templateDuration в TimeSpan, исходное значение: {templateDuration}");
+ logger.LogError($"templateDuration = null.");
return null;
}
-
- return expirationDateUTC.Add(-duration);
}
}
diff --git a/PARR.Master/Services/OrderMasterService.cs b/PARR.Master/Services/OrderMasterService.cs
index db6991bf..94f78d48 100644
--- a/PARR.Master/Services/OrderMasterService.cs
+++ b/PARR.Master/Services/OrderMasterService.cs
@@ -40,15 +40,18 @@ namespace PARR.Master.Services
public async Task ManageOrdersAsync()
{
+ // логика работы описана в документации проекта
+
logger.LogInformation($"--- Начало поиска нарядов ---");
- //ищем наряды в статусе 1 и 2, присваиваем им историю работы агента, меняем стаус наряда
+ //ищем наряды в статусе 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);
}
@@ -84,56 +87,87 @@ namespace PARR.Master.Services
///
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.DateCreated <= order.GenerateDate!.Value.AddSeconds(order.Template!.ApplicationsInWork!.AgentTimeOutSec!.Value)
+ && t.DateCreated <= order.GenerateDate!.Value.Add(order.Template!.ApplicationsInWork!.TemplateDurationTimeSpan!.Value)
&& t.OrderId == null
)
+ .OrderBy(t => t.DateCreated)
.ToListAsync();
- logger.LogInformation($"Для наряда {order.Id}, {order.Number} надено новых историй агентов: {agentHistory.Count()} шт. Присваиваю истории ИД наряда.");
+ logger.LogInformation($"Для наряда {order.Id}, {order.Number} найдено новых историй агентов: {agentHistory.Count()} шт.");
foreach (var historyItem in agentHistory)
+ {
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 Ищем статус "Агент начал выполнять задание"
- 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 Ищем статус "Агент завершил выполнение задания"
- 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)
{
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)
{
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==false && isAgentEnded == false && )
- //{
- // // ставим Выполнен, так как превысил таймаут
- // order.NextStatusCode = (int)OrderStatusEnum.Complete;
- // logger.LogInformation($"Для наряда {order.Id}, {order.Number} меню статус на {OrderStatusEnum.Complete}");
- //}
+ //закрываем по таймауту. Если есть начало, и нет завершения по АгентТаймаут, то закрываем наряд.
+ if (isAgentStarted == true && isAgentEnded == false)
+ {
+ var lastStrartDate = allHistory.Last(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.Start).DateCreated;
+ var timeout = (double)order.Template!.ApplicationsInWork!.AgentTimeOutSec!;
+
+ 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())
{
logger.LogError($"Ошибка при сохранении НАРЯДА, id: {order.Id}");
}
- logger.LogInformation($"Закончил работу с нарядом {order.Id}, {order.Number}");
+ logger.LogInformation($"Закончил работу с нарядом {order.Id}, {order.Number}");
}
@@ -173,7 +207,8 @@ namespace PARR.Master.Services
&& t.Template!.ApplicationsInWork!.IsAgent == true
&& t.GenerateDate.HasValue
&& t.Template!.ApplicationsInWork!.AgentTimeOutSec.HasValue
- );
+ && string.IsNullOrEmpty(t.Template!.ApplicationsInWork!.TemplateDuration) == false
+ ).OrderBy(t => t.DateCreated);
}
}
}