feat(api): Вынес логику формирования расписания в сервис IEsppSchTypeConfigService. В респонс шаблона добавил отображение расписания. Получение шаблона по ИД.

This commit is contained in:
Mikhail Trubnikov
2023-10-12 12:06:47 +10:00
parent c2c381896b
commit b177c0cc27
10 changed files with 186 additions and 88 deletions

View File

@@ -55,7 +55,7 @@
public static class Template
{
public const string GetAll = Base + "/templates/";
//public const string Get = Base + "/templates/" + getParam;
public const string Get = Base + "/templates/" + getParam;
//public const string SetOkStatus = Base + "/templates/" + getParam + "/status/ok";
//public const string GetByStatusCode = Base + "/templates/status/{statusCode}";
@@ -63,7 +63,7 @@
public const string getParam = "{id}";
}
public static class TemplateScheduleEspp
public static class TemplateScheduleEspp
{
public const string Get = Base + "/templates/" + templateId + "/schedule-esppid";

View File

@@ -39,7 +39,7 @@
{
public Guid Id { get; set; }
public required string Name { get; set; }
public required string Value { get; set; }
}
}

View File

@@ -16,68 +16,19 @@
public required string Solution { get; set; }
public required string TemplateDuration { get; set; }
//work
//public required string Title { get; set; }
//public required string SlaInterval { get; set; }
//public required string Description { get; set; }
//public required string Resolution { get; set; }
//public required string RzdMTNKjob { get; set; }
public WorkResponse? Work { get; set; }
//host
//public required string Assignment { get; set; }
//public required string Branch { get; set; }
//public required string ConfigurationItem { get; set; }
public HostResponse? Host { get; set; }
//process
//public required string RzdMTNKprocess { get; set; }
public WorkResponse? Work { get; set; }
public ProcessResponse? Process { get; set; }
//subprocess
//public required string RzdMTNKsubprocess { get; set; }
public SubprocessResponse? Subprocess { get; set; }
//tnk
//public required string RzdMTNKtnk { get; set; }
public TnkResponse? Tnk { get; set; }
public List<RobotConfigurationResponse>? SyncStatus { get; set; }
//TODO: тут сделать биндинг!!!!!! !!!!!! !!!!!! !!!!!! !!!!!! !!!!!!
/// <summary>
/// Расписание
/// </summary>
public EsppScheduleResponse? Schedule { get; set; }
}
//public class TemplateStringResponse
//{
// public required string Name { get; set; }
// public required string IsActive { get; set; }
// public required string Assignment { get; set; }
// public required string Title { get; set; }
// public required string Category { get; set; }
// public required string Branch { get; set; }
// public required string SlaInterval { get; set; }
// public required string ConfigurationItem { get; set; }
// public required string ContactName { get; set; }
// public required string Description { get; set; }
// public required string ResolutionCode { get; set; }
// public required string Resolution { get; set; }
// public required string RzdMTNKprocess { get; set; }
// public required string RzdMTNKprocessId { get; set; }
// public required string RzdMTNKsubprocess { get; set; }
// public required string RzdMTNKsubprocessId { get; set; }
// public required string RzdMTNKtnk { get; set; }
// public required string RzdMTNKtnkId { get; set; }
// public required string RzdMTNKjob { get; set; }
// public required string RzdMTNKjobId { get; set; }
// public required string Id { get; set; }
// public required string StatusCode { get; set; }
//}
}

View File

@@ -70,20 +70,23 @@ namespace PARR.API.Controllers.V1
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
//[HttpGet(ApiRoutes.Template.Get)]
//public async Task<IActionResult> GetById([FromRoute] Guid id)
//{
// var template = await templateService.GetWithIncludes()
// .AsSplitQuery()
// .FirstOrDefaultAsync(t => t.Id == id);
[HttpGet(ApiRoutes.Template.Get)]
public async Task<IActionResult> GetById([FromRoute] Guid id)
{
var template = await templateService.GetWithIncludes()
.Include(t => t.RobotConfigurations).ThenInclude(t => t.Robot)
.Include(t => t.RobotConfigurations).ThenInclude(t => t.TaskStatus)
.Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus)
.AsSplitQuery()
.FirstOrDefaultAsync(t => t.Id == id);
// if (template == null)
// return NotFound();
if (template == null)
return NotFound();
// var response = mapper.Map<TemplateResponse>(template);
var response = mapper.Map<TemplateResponse>(template);
// return Ok(new Response<TemplateResponse>(response, true));
//}
return Ok(new Response<TemplateResponse>(response, true));
}
/// <summary>
/// Получить один шаблон по заданному статусу

View File

@@ -2,6 +2,7 @@
using PARR.API.Contracts.V1.Responses;
using PARR.API.MappingProfiles.Resolvers;
using PARR.BLL.Helpers;
using PARR.DAL.DomainModels;
using PARR.DAL.Models;
using PARR.DAL.Models.V1;
@@ -42,7 +43,8 @@ namespace PARR.API.MappingProfiles
.ForMember(d => d.Initiator, o => o.MapFrom<TemplateInitiatorResolver>())
.ForMember(d => d.ClosingCode, o => o.MapFrom<TemplateClosingCodeResolver>())
.ForMember(d => d.Category, o => o.MapFrom<TemplateCategoryResolver>())
.ForMember(d => d.SyncStatus, o => o.MapFrom(s => s.RobotConfigurations));
.ForMember(d => d.SyncStatus, o => o.MapFrom(s => s.RobotConfigurations))
.ForMember(d => d.Schedule, o => o.MapFrom<TemplateScheduleResolver>());
// === Template ===
CreateMap<Template, TemplateScheduleEsppIdResponse>();
@@ -130,6 +132,19 @@ namespace PARR.API.MappingProfiles
.ForMember(d => d.RobotStatus, o => o.MapFrom(s => s.RobotStatus));
// --- EsppSch ---
CreateMap<EsppSchTypeSchedule, EsppScheduleTypeScheduleResponse>();
CreateMap<EsppSchType, EsppScheduleTypeResponse>();
CreateMap<EsppSchTypeValue, EsppScheduleTypeValueResponse>();
CreateMap<EsppScheduleValDto, EsppScheduleValResponse>()
.ForMember(d => d.Order, o => o.MapFrom(s => s.Order))
.ForMember(d => d.Value, o => o.MapFrom(s => s.Value))
.ForMember(d => d.Type, o => o.MapFrom(s => s.Type));
// === EsppSch ===
}
}
}

View File

@@ -8,29 +8,36 @@ namespace PARR.API.MappingProfiles.Resolvers
public class RobotTaskScheduleSchResolver : IValueResolver<RobotConfiguration, RobotTaskScheduleResponse, List<RobotTaskScheduleSchResponse>?>
{
private readonly IEsppSchTypeConfigService esppConfigService;
private readonly ILogger<RobotTaskScheduleSchResolver> logger;
public RobotTaskScheduleSchResolver(IEsppSchTypeConfigService esppConfigService)
public RobotTaskScheduleSchResolver(
IEsppSchTypeConfigService esppConfigService,
ILogger<RobotTaskScheduleSchResolver> logger
)
{
this.esppConfigService = esppConfigService;
this.logger = logger;
}
public List<RobotTaskScheduleSchResponse>? Resolve(RobotConfiguration source, RobotTaskScheduleResponse destination, List<RobotTaskScheduleSchResponse>? destMember, ResolutionContext context)
{
//todo: может вынести эту логику в сервис?
var appInWorksId = source.Template!.ApplicationInWorkId;
var configs = esppConfigService.GetWithSchIncludes()
.Where(t => t.EsppSchValues.Any(x => x.ApplicationsInWorkId == appInWorksId))
.ToList();
var schedule = esppConfigService.GetEsppScheduleDto(appInWorksId);
var response = configs.Select(conf =>
new RobotTaskScheduleSchResponse
{
Order = conf.Order,
Type = conf.EsppSchType!.Name,
TypeCode = conf.EsppSchType!.Id,
Value = conf.EsppSchValues.First().EsppSchTypeValue!.Value
});
if (schedule == null)
{
logger.LogError($"RobotTaskScheduleSchResolver: Не смог замапить расписание для робота, так как оно null. appInWorksId: {appInWorksId}");
return null;
}
var response = schedule.Values.Select(t => new RobotTaskScheduleSchResponse
{
Order = t.Order,
Type = t.Type.Name,
TypeCode = t.Type.Id,
Value = t.Value.Value
});
return response.OrderBy(t => t.Order).ToList();
}

View File

@@ -0,0 +1,44 @@
using AutoMapper;
using PARR.API.Contracts.V1.Responses;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces;
namespace PARR.API.MappingProfiles.Resolvers
{
public class TemplateScheduleResolver : IValueResolver<Template, TemplateResponse, EsppScheduleResponse?>
{
private readonly IEsppSchTypeConfigService esppConfigService;
private readonly ILogger<TemplateScheduleResolver> logger;
private readonly IMapper mapper;
public TemplateScheduleResolver(
IEsppSchTypeConfigService esppConfigService,
ILogger<TemplateScheduleResolver> logger,
IMapper mapper
)
{
this.esppConfigService = esppConfigService;
this.logger = logger;
this.mapper = mapper;
}
public EsppScheduleResponse? Resolve(Template source, TemplateResponse destination, EsppScheduleResponse? destMember, ResolutionContext context)
{
var schedule = esppConfigService.GetEsppScheduleDto(source.ApplicationInWorkId);
if (schedule == null)
{
logger.LogError($"TemplateScheduleResolver: Не смог замапить расписание для робота, так как оно null. appInWorksId: {source.ApplicationInWorkId}");
return null;
}
var response = new EsppScheduleResponse
{
TypeSchedule = mapper.Map<EsppScheduleTypeScheduleResponse>(schedule.TypeSchedule),
Values = mapper.Map<List<EsppScheduleValResponse>>(schedule.Values).OrderBy(t => t.Order).ToList()
};
return response;
}
}
}

View File

@@ -0,0 +1,23 @@
using PARR.DAL.Models;
namespace PARR.DAL.DomainModels
{
/// <summary>
/// Расписание ЕСПП в нормальном виде
/// </summary>
public class EsppScheduleDto
{
public required EsppSchTypeSchedule TypeSchedule { get; set; }
public required List<EsppScheduleValDto> Values { get; set; }
}
public class EsppScheduleValDto
{
public int Order { get; set; }
public required EsppSchType Type { get; set; }
public required EsppSchTypeValue Value { get; set; }
}
}

View File

@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using PARR.DAL.Context;
using PARR.DAL.DomainModels;
using PARR.DAL.Models;
using PARR.DAL.Services.Abstracts;
using PARR.DAL.Services.Interfaces;
@@ -30,12 +31,51 @@ namespace PARR.DAL.Services.Implementations
.ThenInclude(t => t!.EsppSchValues);
}
//public IQueryable<EsppSchTypeConfig> GetScheduleByAppInWorks(Guid applicationInWorksId)
//{
// var configs = GetWithSchIncludes()
// .Where(t => t.EsppSchValues.Any(x => x.ApplicationsInWorkId == applicationInWorksId))
// .ToList();
public async Task<EsppScheduleDto?> GetEsppScheduleDtoAsync(Guid applicationInWorksId)
{
//Формирует расписание в нормальном понятном виде из БД
//}
var configs = await GetWithSchIncludes()
.Where(t => t.EsppSchValues.Any(x => x.ApplicationsInWorkId == applicationInWorksId))
.ToListAsync();
if (!configs.Any())
return null;
var values = new List<EsppScheduleValDto>();
foreach (var config in configs)
{
var value = new EsppScheduleValDto
{
Order = config.Order,
Type = config.EsppSchType!,
Value = config.EsppSchValues.First().EsppSchTypeValue!
};
values.Add(value);
}
var dto = new EsppScheduleDto
{
TypeSchedule = configs.First().EsppSchTypeSchedule!,
Values = values.OrderBy(t => t.Order).ToList()
};
return dto;
}
public EsppScheduleDto? GetEsppScheduleDto(Guid applicationInWorksId)
{
var result = Task.Run(async () =>
{
return await GetEsppScheduleDtoAsync(applicationInWorksId);
}).Result;
return result;
}
}
}

View File

@@ -1,10 +1,25 @@
using PARR.DAL.Models;
using PARR.DAL.DomainModels;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces.Base;
namespace PARR.DAL.Services.Interfaces
{
public interface IEsppSchTypeConfigService : IBaseService<EsppSchTypeConfig>
{
/// <summary>
/// Формирует расписание в нормальном понятном виде из БД синхронно
/// </summary>
/// <param name="applicationInWorksId"></param>
/// <returns></returns>
EsppScheduleDto? GetEsppScheduleDto(Guid applicationInWorksId);
/// <summary>
/// Формирует расписание в нормальном понятном виде из БД асинхронно
/// </summary>
/// <param name="applicationInWorksId"></param>
/// <returns></returns>
Task<EsppScheduleDto?> GetEsppScheduleDtoAsync(Guid applicationInWorksId);
IQueryable<EsppSchTypeConfig> GetWithSchIncludes();
}
}