From 8ebdcd6d8a01a0defd32041cffbed00b3525a11f Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Wed, 11 Oct 2023 11:10:35 +1000 Subject: [PATCH] =?UTF-8?q?feat(api):=20=D0=94=D0=BE=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B0=D0=BB=20=D1=80=D0=B5=D1=81=D0=BF=D0=BE=D0=BD=D1=81=20Rob?= =?UTF-8?q?otTaskScheduleResponse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../V1/Responses/RobotTaskScheduleResponse.cs | 24 +++++++++++- .../Controllers/V1/RobotTaskController.cs | 18 ++++++--- .../DomainToResponseProfile.cs | 11 +++++- .../RobotTaskScheduleExcludeResolver.cs | 22 +++++++++++ .../RobotTaskScheduleRepeatRangeResolver.cs | 22 +++++++++++ .../Resolvers/RobotTaskScheduleSchResolver.cs | 37 +++++++++++++++++++ .../RobotTaskScheduleTimezoneResolver.cs | 22 +++++++++++ PARR.BLL/Helpers/EsppScheduleHelpers.cs | 20 ++++++++++ PARR.DAL/ParrDalInstaller.cs | 1 + .../EsppSchTypeConfigService.cs | 33 +++++++++++++++++ .../Interfaces/IEsppSchTypeConfigService.cs | 10 +++++ 11 files changed, 212 insertions(+), 8 deletions(-) create mode 100644 PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleExcludeResolver.cs create mode 100644 PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleRepeatRangeResolver.cs create mode 100644 PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleSchResolver.cs create mode 100644 PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleTimezoneResolver.cs create mode 100644 PARR.BLL/Helpers/EsppScheduleHelpers.cs create mode 100644 PARR.DAL/Services/Implementations/EsppSchTypeConfigService.cs create mode 100644 PARR.DAL/Services/Interfaces/IEsppSchTypeConfigService.cs diff --git a/PARR.API/Contracts/V1/Responses/RobotTaskScheduleResponse.cs b/PARR.API/Contracts/V1/Responses/RobotTaskScheduleResponse.cs index 9a28e33c..41d69fdf 100644 --- a/PARR.API/Contracts/V1/Responses/RobotTaskScheduleResponse.cs +++ b/PARR.API/Contracts/V1/Responses/RobotTaskScheduleResponse.cs @@ -21,6 +21,28 @@ public string? Description { get; set; } - // TODO: + public required string Exclude { get; set; } + + public required string Timezone { get; set; } + + public required string RepeatRange { get; set; } + + public required string GenerationTime { get; set; } + + public required string NextStart { get; set; } + + /// + /// Тип задания: ругелярно, еженедельно... + /// + public required string ScheduleType { get; set; } + + public List? Schedule { get; set; } + } + + public class RobotTaskScheduleSchResponse + { + public required string Type { get; set; } + public required string Value { get; set; } + public int Order { get; set; } } } diff --git a/PARR.API/Controllers/V1/RobotTaskController.cs b/PARR.API/Controllers/V1/RobotTaskController.cs index c6030378..bbf5157c 100644 --- a/PARR.API/Controllers/V1/RobotTaskController.cs +++ b/PARR.API/Controllers/V1/RobotTaskController.cs @@ -42,8 +42,7 @@ namespace PARR.API.Controllers.V1 await robotConfigurationService.FindUnfulfilledTaskAndSetRobotErrorStatusAsync(settingsFromDb.RobotAttemptsNumber, settingsFromDb.RobotWaitTime); var query = robotConfigurationService.Get() - .Where(t => t.RobotCode == (int)robotCode && t.TaskStatusCode == (int)taskStatusCode) - .AsSplitQuery(); + .Where(t => t.RobotCode == (int)robotCode && t.TaskStatusCode == (int)taskStatusCode); switch (robotCode) { @@ -55,11 +54,19 @@ namespace PARR.API.Controllers.V1 .ThenInclude(w => w!.Work) .ThenInclude(t => t!.Tnk) .ThenInclude(s => s!.Subprocess) - .ThenInclude(p => p!.Process); + .ThenInclude(p => p!.Process) + .AsSplitQuery(); break; case RobotsEnum.ScheduleOrder: + // тут не делаем AsSplitQuery, не может подтянуть все таблицы query = query.Include(t => t.Template) - .ThenInclude(t => t!.Host).ThenInclude(t => t!.ResponseArea); + .ThenInclude(t => t!.Host).ThenInclude(t => t!.ResponseArea) + .Include(t => t.Template) + .ThenInclude(t => t!.ApplicationsInWork) + .ThenInclude(t => t!.EsppSchValues) + .ThenInclude(t => t!.EsppSchTypeConfig) + .ThenInclude(t => t!.EsppSchTypeSchedule) + ; //todo: include break; default: @@ -79,7 +86,8 @@ namespace PARR.API.Controllers.V1 //и что текущая попытка не больше разрешенной(берется из настроек, поле `RobotAttemptsNumber`) - если это так, берется эта запись. var endDate = DateTimeOffset.UtcNow.Add(-settingsFromDb.RobotWaitTime); - task = await query.FirstOrDefaultAsync(t => + task = await query + .FirstOrDefaultAsync(t => t.RobotStatusCode == (int)RobotStatusEnum.InProgress && t.AttemptsNumber < settingsFromDb.RobotAttemptsNumber && t.LastRobotStatusUpdated < endDate diff --git a/PARR.API/MappingProfiles/DomainToResponseProfile.cs b/PARR.API/MappingProfiles/DomainToResponseProfile.cs index cda40a20..ff57d93d 100644 --- a/PARR.API/MappingProfiles/DomainToResponseProfile.cs +++ b/PARR.API/MappingProfiles/DomainToResponseProfile.cs @@ -1,6 +1,7 @@ using AutoMapper; using PARR.API.Contracts.V1.Responses; using PARR.API.MappingProfiles.Resolvers; +using PARR.BLL.Helpers; using PARR.DAL.Models; using PARR.DAL.Models.V1; @@ -97,7 +98,6 @@ namespace PARR.API.MappingProfiles .ForMember(d => d.WorkName, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Name)) .ForMember(d => d.WorkEsppId, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.EsppId)); - //TODO: сделать маппинг!!! CreateMap() .ForMember(d => d.EsppId, o => o.MapFrom(s => s.Template!.ScheduleEsppId)) .ForMember(d => d.ScheduleName, o => o.MapFrom(s => s.Template!.Name)) @@ -106,7 +106,14 @@ namespace PARR.API.MappingProfiles .ForMember(d => d.TemplateName, o => o.MapFrom(s => s.Template!.Name)) .ForMember(d => d.TemplateId, o => o.MapFrom(s => s.Template!.Id)) .ForMember(d => d.WorkGroup, o => o.MapFrom(s => s.Template!.Host!.WorkGroup)) - ; + .ForMember(d => d.Exclude, o => o.MapFrom()) + .ForMember(d => d.Timezone, o => o.MapFrom()) + .ForMember(d => d.RepeatRange, o => o.MapFrom()) + .ForMember(d => d.GenerationTime, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.ScheduleGenerationTime)) + .ForMember(d => d.NextStart, o => o.MapFrom(s => EsppScheduleHelpers.GetFirstStart(s.Template!.ApplicationsInWork!.ScheduleStartDate, s.Template!.ApplicationsInWork!.ScheduleGenerationTime))) + .ForMember(d => d.ScheduleType, o => o.MapFrom(s => + s.Template!.ApplicationsInWork!.EsppSchValues!.First()!.EsppSchTypeConfig!.EsppSchTypeSchedule!.Description)) + .ForMember(d => d.Schedule, o => o.MapFrom()); // === RobotConfiguration === CreateMap(); diff --git a/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleExcludeResolver.cs b/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleExcludeResolver.cs new file mode 100644 index 00000000..f08e5ac4 --- /dev/null +++ b/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleExcludeResolver.cs @@ -0,0 +1,22 @@ +using AutoMapper; +using PARR.API.Contracts.V1.Responses; +using PARR.DAL.Contracts; +using PARR.DAL.Models; + +namespace PARR.API.MappingProfiles.Resolvers +{ + public class RobotTaskScheduleExcludeResolver : IValueResolver + { + private readonly SettingsFromDb settingsFromDb; + + public RobotTaskScheduleExcludeResolver(SettingsFromDb settingsFromDb) + { + this.settingsFromDb = settingsFromDb; + } + + public string Resolve(RobotConfiguration source, RobotTaskScheduleResponse destination, string destMember, ResolutionContext context) + { + return settingsFromDb.ScheduleExclude; + } + } +} diff --git a/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleRepeatRangeResolver.cs b/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleRepeatRangeResolver.cs new file mode 100644 index 00000000..5cc49c57 --- /dev/null +++ b/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleRepeatRangeResolver.cs @@ -0,0 +1,22 @@ +using AutoMapper; +using PARR.API.Contracts.V1.Responses; +using PARR.DAL.Contracts; +using PARR.DAL.Models; + +namespace PARR.API.MappingProfiles.Resolvers +{ + public class RobotTaskScheduleRepeatRangeResolver : IValueResolver + { + private readonly SettingsFromDb settingsFromDb; + + public RobotTaskScheduleRepeatRangeResolver(SettingsFromDb settingsFromDb) + { + this.settingsFromDb = settingsFromDb; + } + + public string Resolve(RobotConfiguration source, RobotTaskScheduleResponse destination, string destMember, ResolutionContext context) + { + return settingsFromDb.ScheduleRepeatRange; + } + } +} diff --git a/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleSchResolver.cs b/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleSchResolver.cs new file mode 100644 index 00000000..dcd223f3 --- /dev/null +++ b/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleSchResolver.cs @@ -0,0 +1,37 @@ +using AutoMapper; +using PARR.API.Contracts.V1.Responses; +using PARR.DAL.Models; +using PARR.DAL.Services.Interfaces; + +namespace PARR.API.MappingProfiles.Resolvers +{ + public class RobotTaskScheduleSchResolver : IValueResolver?> + { + private readonly IEsppSchTypeConfigService esppConfigService; + + public RobotTaskScheduleSchResolver(IEsppSchTypeConfigService esppConfigService) + { + this.esppConfigService = esppConfigService; + } + + public List? Resolve(RobotConfiguration source, RobotTaskScheduleResponse destination, List? destMember, ResolutionContext context) + { + //todo: может вынести эту логику в сервис? + var appInWorksId = source.Template!.ApplicationInWorkId; + + var configs = esppConfigService.GetWithSchIncludes() + .Where(t => t.EsppSchValues.Any(x => x.ApplicationsInWorkId == appInWorksId)) + .ToList(); + + var response = configs.Select(conf => + new RobotTaskScheduleSchResponse + { + Order = conf.Order, + Type = conf.EsppSchType!.Name, + Value = conf.EsppSchValues.First().EsppSchTypeValue!.Value + }); + + return response.OrderBy(t => t.Order).ToList(); + } + } +} diff --git a/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleTimezoneResolver.cs b/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleTimezoneResolver.cs new file mode 100644 index 00000000..47f7cec1 --- /dev/null +++ b/PARR.API/MappingProfiles/Resolvers/RobotTaskScheduleTimezoneResolver.cs @@ -0,0 +1,22 @@ +using AutoMapper; +using PARR.API.Contracts.V1.Responses; +using PARR.DAL.Contracts; +using PARR.DAL.Models; + +namespace PARR.API.MappingProfiles.Resolvers +{ + public class RobotTaskScheduleTimezoneResolver : IValueResolver + { + private readonly SettingsFromDb settingsFromDb; + + public RobotTaskScheduleTimezoneResolver(SettingsFromDb settingsFromDb) + { + this.settingsFromDb = settingsFromDb; + } + + public string Resolve(RobotConfiguration source, RobotTaskScheduleResponse destination, string destMember, ResolutionContext context) + { + return settingsFromDb.ScheduleTimezone; + } + } +} diff --git a/PARR.BLL/Helpers/EsppScheduleHelpers.cs b/PARR.BLL/Helpers/EsppScheduleHelpers.cs new file mode 100644 index 00000000..b2682420 --- /dev/null +++ b/PARR.BLL/Helpers/EsppScheduleHelpers.cs @@ -0,0 +1,20 @@ +using System.Globalization; + +namespace PARR.BLL.Helpers +{ + public static class EsppScheduleHelpers + { + /// + /// Получить дату первого старта в формате ЕСПП + /// + /// + /// + /// + public static string GetFirstStart(DateOnly startDate, TimeSpan time) + { + var date = new DateTime(startDate.Year, startDate.Month, startDate.Day, time.Hours, time.Minutes, time.Seconds); + + return date.ToString("dd/MM/yy HH:mm:ss", CultureInfo.InvariantCulture); + } + } +} diff --git a/PARR.DAL/ParrDalInstaller.cs b/PARR.DAL/ParrDalInstaller.cs index 92b1d10e..c42ae526 100644 --- a/PARR.DAL/ParrDalInstaller.cs +++ b/PARR.DAL/ParrDalInstaller.cs @@ -55,6 +55,7 @@ namespace PARR.DAL services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } /// diff --git a/PARR.DAL/Services/Implementations/EsppSchTypeConfigService.cs b/PARR.DAL/Services/Implementations/EsppSchTypeConfigService.cs new file mode 100644 index 00000000..cbae73e5 --- /dev/null +++ b/PARR.DAL/Services/Implementations/EsppSchTypeConfigService.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using PARR.DAL.Context; +using PARR.DAL.Models; +using PARR.DAL.Services.Abstracts; +using PARR.DAL.Services.Interfaces; + +namespace PARR.DAL.Services.Implementations +{ + internal class EsppSchTypeConfigService : BaseService, IEsppSchTypeConfigService + { + private readonly DataContext dataContext; + + public EsppSchTypeConfigService(DataContext dataContext, ILogger logger) : base(logger) + { + this.dataContext = dataContext; + } + + protected override DbSet EntitySet => dataContext.EsppSchTypeConfigs; + + protected override DataContext EntitiContext => dataContext; + + public IQueryable GetWithSchIncludes() + { + return Get() + .Include(t => t.EsppSchValues) + .Include(t => t.EsppSchTypeSchedule) + .Include(t => t.EsppSchType) + .ThenInclude(t => t!.EsppSchTypeValues) + .ThenInclude(t => t!.EsppSchValues); + } + } +} diff --git a/PARR.DAL/Services/Interfaces/IEsppSchTypeConfigService.cs b/PARR.DAL/Services/Interfaces/IEsppSchTypeConfigService.cs new file mode 100644 index 00000000..97d94a06 --- /dev/null +++ b/PARR.DAL/Services/Interfaces/IEsppSchTypeConfigService.cs @@ -0,0 +1,10 @@ +using PARR.DAL.Models; +using PARR.DAL.Services.Interfaces.Base; + +namespace PARR.DAL.Services.Interfaces +{ + public interface IEsppSchTypeConfigService : IBaseService + { + IQueryable GetWithSchIncludes(); + } +}