From af4a0b60b8c376e55483f2224f0a9f61b5389041 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Thu, 5 Oct 2023 16:56:02 +1000 Subject: [PATCH] =?UTF-8?q?feat(api):=20=D0=9B=D0=BE=D0=B3=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=81=D0=BC=D0=B5=D0=BD=D1=8B=20=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=82=D1=83=D1=81=D0=BE=D0=B2=20=D0=B4=D0=BB=D1=8F=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B9=20=D1=80=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0.=20RobotTaskController?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PARR.API/Contracts/V1/ApiRoutes.cs | 8 + .../Responses/RobotConfigurationResponse.cs | 7 + .../V1/Responses/RobotTaskScheduleResponse.cs | 7 + .../V1/Responses/RobotTaskTemplateResponse.cs | 31 + .../Controllers/V1/RobotTaskController.cs | 109 + .../V1/RobotTemplateHistoryController.cs | 40 +- PARR.API/Controllers/V1/TemplateController.cs | 14 +- .../DomainToResponseProfile.cs | 2 +- PARR.DAL/Context/DataContext.cs | 10 +- ...tatusTemplateEnum.cs => TaskStatusEnum.cs} | 2 +- ...20231005045908_TblUpdTemplates.Designer.cs | 2040 +++++++++++++++++ .../20231005045908_TblUpdTemplates.cs | 268 +++ .../Migrations/DataContextModelSnapshot.cs | 121 +- PARR.DAL/Models/RobotConfiguration.cs | 2 +- PARR.DAL/Models/RobotHistory.cs | 2 +- PARR.DAL/Models/RobotTemplateHistory.cs | 2 +- .../Models/{StatusTask.cs => TaskStatus.cs} | 4 +- PARR.DAL/Models/Template.cs | 27 +- .../RobotConfigurationService.cs | 94 + .../Implementations/StatusTemplateService.cs | 4 +- .../Implementations/TemplateService.cs | 37 + .../Interfaces/IRobotConfigurationService.cs | 32 +- .../Interfaces/IStatusTemplateService.cs | 2 +- .../MappingProfiles/DomainToDomainProfile.cs | 2 +- PARR.EsppTemplateSync/Services/Manager.cs | 2 +- .../Services/TemplateManager.cs | 36 +- 26 files changed, 2779 insertions(+), 126 deletions(-) create mode 100644 PARR.API/Contracts/V1/Responses/RobotConfigurationResponse.cs create mode 100644 PARR.API/Contracts/V1/Responses/RobotTaskScheduleResponse.cs create mode 100644 PARR.API/Contracts/V1/Responses/RobotTaskTemplateResponse.cs create mode 100644 PARR.API/Controllers/V1/RobotTaskController.cs rename PARR.DAL/Contracts/{StatusTemplateEnum.cs => TaskStatusEnum.cs} (75%) create mode 100644 PARR.DAL/Migrations/20231005045908_TblUpdTemplates.Designer.cs create mode 100644 PARR.DAL/Migrations/20231005045908_TblUpdTemplates.cs rename PARR.DAL/Models/{StatusTask.cs => TaskStatus.cs} (92%) diff --git a/PARR.API/Contracts/V1/ApiRoutes.cs b/PARR.API/Contracts/V1/ApiRoutes.cs index cc114b48..85a74f1c 100644 --- a/PARR.API/Contracts/V1/ApiRoutes.cs +++ b/PARR.API/Contracts/V1/ApiRoutes.cs @@ -97,6 +97,14 @@ public const string GetAll = Base + "/robot-history-levels/"; } + public static class RobotTask + { + public const string GetByRobotAndStatusTask = Base + "/robot-tasks/" + robotCode + "/statuses/" + taskStatusCode; + + public const string robotCode = "{robotCode}"; + public const string taskStatusCode = "{taskStatusCode}"; + } + //public static class Layer //{ diff --git a/PARR.API/Contracts/V1/Responses/RobotConfigurationResponse.cs b/PARR.API/Contracts/V1/Responses/RobotConfigurationResponse.cs new file mode 100644 index 00000000..166d30cc --- /dev/null +++ b/PARR.API/Contracts/V1/Responses/RobotConfigurationResponse.cs @@ -0,0 +1,7 @@ +namespace PARR.API.Contracts.V1.Responses +{ + public class RobotConfigurationResponse + { + + } +} diff --git a/PARR.API/Contracts/V1/Responses/RobotTaskScheduleResponse.cs b/PARR.API/Contracts/V1/Responses/RobotTaskScheduleResponse.cs new file mode 100644 index 00000000..50619a56 --- /dev/null +++ b/PARR.API/Contracts/V1/Responses/RobotTaskScheduleResponse.cs @@ -0,0 +1,7 @@ +namespace PARR.API.Contracts.V1.Responses +{ + public class RobotTaskScheduleResponse + { + //TODO: + } +} diff --git a/PARR.API/Contracts/V1/Responses/RobotTaskTemplateResponse.cs b/PARR.API/Contracts/V1/Responses/RobotTaskTemplateResponse.cs new file mode 100644 index 00000000..d85f86c4 --- /dev/null +++ b/PARR.API/Contracts/V1/Responses/RobotTaskTemplateResponse.cs @@ -0,0 +1,31 @@ +namespace PARR.API.Contracts.V1.Responses +{ + public class RobotTaskTemplateResponse + { + public bool IsActive { get; set; } + public required string ClosingCode { get; set; } + public required string FullDescription { get; set; } + public required string ShortDescription { get; set; } + public required string Solution { get; set; } + public required string ResponseArea { get; set; } + public required string TemplateDuration { get; set; } + public required string Initiator { get; set; } + public required string WorkGroup { get; set; } + public required string Ek { get; set; } + public required string Name { get; set; } + public required string Category { get; set; } + + + public required string ProcessName { get; set; } + public required string ProcessEsppId { get; set; } + + public required string SubprocessName { get; set; } + public required string SubprocessEsppId { get; set; } + + public required string TnkName { get; set; } + public required string TnkEsppId { get; set; } + + public required string WorkName { get; set; } + public required string WorkEsppId { get; set; } + } +} diff --git a/PARR.API/Controllers/V1/RobotTaskController.cs b/PARR.API/Controllers/V1/RobotTaskController.cs new file mode 100644 index 00000000..e94214c9 --- /dev/null +++ b/PARR.API/Controllers/V1/RobotTaskController.cs @@ -0,0 +1,109 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using PARR.API.Contracts.V1; +using PARR.API.Contracts.V1.Responses; +using PARR.API.Contracts.V1.Responses.Base; +using PARR.API.Controllers.V1.Base; +using PARR.DAL.Contracts; +using PARR.DAL.Models; +using PARR.DAL.Services.Interfaces; + +namespace PARR.API.Controllers.V1 +{ + public class RobotTaskController : BaseApiController + { + private readonly IMapper mapper; + private readonly SettingsFromDb settingsFromDb; + private readonly IRobotConfigurationService robotConfigurationService; + + public RobotTaskController( + IMapper mapper, + SettingsFromDb settingsFromDb, + IRobotConfigurationService robotConfigurationService + ) + { + this.mapper = mapper; + this.settingsFromDb = settingsFromDb; + this.robotConfigurationService = robotConfigurationService; + } + + + /// + /// Получить задание для робота по коду робота и по статусу задания + /// + /// + /// + /// + [HttpGet(ApiRoutes.RobotTask.GetByRobotAndStatusTask)] + public async Task GetByRobotAndStatusTask([FromRoute] RobotsEnum robotCode, [FromRoute] TaskStatusEnum taskStatusCode) + { + //Ищем все задания с превышенным кол-вом попыток и с просроченным временем и ставим им статус ошибки + await robotConfigurationService.FindUnfulfilledTaskAndSetRobotErrorStatusAsync(settingsFromDb.RobotAttemptsNumber, settingsFromDb.RobotWaitTime); + + var query = robotConfigurationService.Get() + .Where(t => t.RobotCode == (int)robotCode && t.TaskStatusCode == (int)taskStatusCode) + .AsSplitQuery(); + + switch (robotCode) + { + case RobotsEnum.TemplateOrder: + query = query.Include(t => t.Template) + .ThenInclude(t => t!.Host).ThenInclude(t => t!.ResponseArea) + .Include(t => t.Template) + .ThenInclude(t => t!.Host) + .Include(t => t.Template) + .ThenInclude(a => a!.ApplicationsInWork) + .ThenInclude(w => w!.Work) + .ThenInclude(t => t!.Tnk) + .ThenInclude(s => s!.Subprocess) + .ThenInclude(p => p!.Process); + break; + case RobotsEnum.ScheduleOrder: + //todo: include + break; + default: + break; + } + + RobotConfiguration? task = null; + + //ищем задание в ожидании, если нашли, выбираем ее + task = await query.FirstOrDefaultAsync(t => t.RobotStatusCode == (int)RobotStatusEnum.Wait); + + if (task == null) + { + //ищем задания в работе, которые можно перезапустить + //Поиск пои `RobotStatusCode` = 22. + //Далее проверяется `LastStatusUpdated`, что время последнего смены статуса не превышает допустимого(берется из настроек, поле `RobotWaitTime`) + //и что текущая попытка не больше разрешенной(берется из настроек, поле `RobotAttemptsNumber`) - если это так, берется эта запись. + + var endDate = DateTimeOffset.UtcNow.Add(-settingsFromDb.RobotWaitTime); + task = await query.FirstOrDefaultAsync(t => + t.RobotStatusCode == (int)RobotStatusEnum.InProgress + && t.AttemptsNumber < settingsFromDb.RobotAttemptsNumber + && t.LastStatusUpdated < endDate + ); + } + + if (task == null) + return NotFound(); + + //TODO: сделать маппинг!!! + + switch (robotCode) + { + case RobotsEnum.TemplateOrder: + //RobotTaskTemplateResponse + return Ok(new Response(mapper.Map(task), true)); + case RobotsEnum.ScheduleOrder: + //RobotTaskScheduleResponse + return Ok(new Response(mapper.Map(task), true)); + default: + break; + } + + return BadRequest(); + } + } +} diff --git a/PARR.API/Controllers/V1/RobotTemplateHistoryController.cs b/PARR.API/Controllers/V1/RobotTemplateHistoryController.cs index 372189c6..b41f1e94 100644 --- a/PARR.API/Controllers/V1/RobotTemplateHistoryController.cs +++ b/PARR.API/Controllers/V1/RobotTemplateHistoryController.cs @@ -95,29 +95,31 @@ namespace PARR.API.Controllers.V1 if (request.IdSeries == null) request.IdSeries = Guid.NewGuid(); - var historyItem = new RobotTemplateHistory - { - Id = Guid.NewGuid(), - HistoryLevel = request.HistoryLevel, - RobotMessage = request.RobotMessage, - EsppMessage = request.EsppMessage, - TemplateId = request.TemplateId, - TemplateStatusCode = template.StatusCode, - IdSeries = request.IdSeries.Value - }; + //var historyItem = new RobotTemplateHistory + //{ + // Id = Guid.NewGuid(), + // HistoryLevel = request.HistoryLevel, + // RobotMessage = request.RobotMessage, + // EsppMessage = request.EsppMessage, + // TemplateId = request.TemplateId, + // TemplateStatusCode = template.StatusCode, + // IdSeries = request.IdSeries.Value + //}; - if (!await historyService.CreateAsync(historyItem) || !await historyService.CommitAsync()) - return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при добавлении записи в историю" } })); + //if (!await historyService.CreateAsync(historyItem) || !await historyService.CommitAsync()) + // return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при добавлении записи в историю" } })); - var createdObj = await historyService.Get() - .Include(t => t.Template) - .Include(t => t.RobotHistoryLevel) - .FirstOrDefaultAsync(t => t.Id == historyItem.Id); + //var createdObj = await historyService.Get() + // .Include(t => t.Template) + // .Include(t => t.RobotHistoryLevel) + // .FirstOrDefaultAsync(t => t.Id == historyItem.Id); - var response = mapper.Map(createdObj); - var createdUri = uriService.GetAllUri(ApiRoutes.RobotTemplateHistory.GetAll) + $"?{nameof(RobotTemplateHistoryQuery.IdSeries)}={createdObj!.IdSeries}"; + //var response = mapper.Map(createdObj); + //var createdUri = uriService.GetAllUri(ApiRoutes.RobotTemplateHistory.GetAll) + $"?{nameof(RobotTemplateHistoryQuery.IdSeries)}={createdObj!.IdSeries}"; - return Created(createdUri, new Response(response, true)); + //return Created(createdUri, new Response(response, true)); + + return Ok("Доделать"); } } diff --git a/PARR.API/Controllers/V1/TemplateController.cs b/PARR.API/Controllers/V1/TemplateController.cs index f6fc2569..13ee4049 100644 --- a/PARR.API/Controllers/V1/TemplateController.cs +++ b/PARR.API/Controllers/V1/TemplateController.cs @@ -51,14 +51,14 @@ namespace PARR.API.Controllers.V1 { switch (filter.StatusCode.Value) { - case (int)StatusTemplateEnum.Ok: - query = query.Where(t => t.StatusCode == (int)StatusTemplateEnum.Ok); + case (int)TaskStatusEnum.Ok: + query = query.Where(t => t.StatusCode == (int)TaskStatusEnum.Ok); break; - case (int)StatusTemplateEnum.Creating: - query = query.Where(t => t.StatusCode == (int)StatusTemplateEnum.Creating); + case (int)TaskStatusEnum.Creating: + query = query.Where(t => t.StatusCode == (int)TaskStatusEnum.Creating); break; - case (int)StatusTemplateEnum.Updating: - query = query.Where(t => t.StatusCode == (int)StatusTemplateEnum.Updating); + case (int)TaskStatusEnum.Updating: + query = query.Where(t => t.StatusCode == (int)TaskStatusEnum.Updating); break; default: break; @@ -170,7 +170,7 @@ namespace PARR.API.Controllers.V1 if (template == null) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Не найден шаблон с id: {id}" } })); - template.StatusCode = (int)StatusTemplateEnum.Ok; + template.StatusCode = (int)TaskStatusEnum.Ok; if (!await templateService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при изменении статуса у шаблона с id: {id}" } })); diff --git a/PARR.API/MappingProfiles/DomainToResponseProfile.cs b/PARR.API/MappingProfiles/DomainToResponseProfile.cs index 0e99ef8e..eb3e866b 100644 --- a/PARR.API/MappingProfiles/DomainToResponseProfile.cs +++ b/PARR.API/MappingProfiles/DomainToResponseProfile.cs @@ -63,7 +63,7 @@ namespace PARR.API.MappingProfiles // === Template === - CreateMap(); + CreateMap(); CreateMap() .ForMember(d => d.Code, o => o.MapFrom(s => s.RobotStatus!.Code)) diff --git a/PARR.DAL/Context/DataContext.cs b/PARR.DAL/Context/DataContext.cs index ac84092d..45de5bc6 100644 --- a/PARR.DAL/Context/DataContext.cs +++ b/PARR.DAL/Context/DataContext.cs @@ -33,7 +33,7 @@ namespace PARR.DAL.Context public DbSet Settings { get; set; } public DbSet RawDataEKs { get; set; } public DbSet