feat(api,dal): исключения расписаний ЕСПП привязаны к JobGroup, удалены константы из настроек. Кол-во шаблонов в Job считается только used. В JobFieldFilter добавлено поле IsInverse.

This commit is contained in:
Mikhail Trubnikov
2025-12-26 11:21:45 +10:00
parent eb57f4b3cd
commit 61c46770e0
29 changed files with 8901 additions and 46 deletions

View File

@@ -24,6 +24,7 @@ using PARR.DAL.Models.Job;
using PARR.DAL.Services.Interfaces;
using PARR.DAL.Services.Interfaces.Job;
using PARR.DAL.Services.Interfaces.Unit;
using System.Net;
using System.Text.Json;
namespace PARR.API.Controllers.V1
@@ -121,7 +122,8 @@ namespace PARR.API.Controllers.V1
foreach (var jobResponse in response)
{
jobResponse.TemplatesCount = await templateService.Get().CountAsync(t => t.JobId == jobResponse.Id);
//jobResponse.TemplatesCount = await templateService.Get().CountAsync(t => t.JobId == jobResponse.Id);
jobResponse.TemplatesCount = await GetCountTemplatesAsync(jobResponse.Id);
}
var paginationResponse = new PagedResponse<JobResponse>(response, true).GetPaginatedProps(paginationFilter, query);
@@ -156,10 +158,10 @@ namespace PARR.API.Controllers.V1
var response = mapper.Map<JobResponse>(job);
response.TemplatesCount = await templateService.Get().CountAsync(t => t.JobId == id);
response.TemplatesCount = await GetCountTemplatesAsync(id); //await templateService.Get().CountAsync(t => t.JobId == id);
var statistics = await GetStatisticsAsync(response.Id);
BindStatistics(response, statistics);
//var statistics = await GetStatisticsAsync(response.Id);
//BindStatistics(response, statistics);
return Ok(new Response<JobResponse>(response, true));
}
@@ -351,10 +353,11 @@ namespace PARR.API.Controllers.V1
.FirstAsync(t => t.Id == orig.Id);
var response = mapper.Map<JobResponse>(updatedJob);
response.TemplatesCount = await templateService.Get().CountAsync(t => t.JobId == id);
response.TemplatesCount = await GetCountTemplatesAsync(id); //await templateService.Get().CountAsync(t => t.JobId == id);
var statistics = await GetStatisticsAsync(response.Id);
BindStatistics(response, statistics);
//не используется
//var statistics = await GetStatisticsAsync(response.Id);
//BindStatistics(response, statistics);
return Ok(new Response<JobResponse>(response, true));
}
@@ -392,7 +395,9 @@ namespace PARR.API.Controllers.V1
orig.UnitFilters.Add(newUnitFilter);
}
/* Писал полноценный апдейт, но Миша сказал что нахрен это - просто все удаляем, а потом создаём заново
#region old
/* Писал полноценный апдейт, но Миша сказал что нахрен это - просто все удаляем, а потом создаём заново... Ох уж этот Миша...
//Сразу удаляем UnitFilter которых нет
var toDelete = orig.UnitFilters.Where(t => !mappedRequest.UnitFilters.Any(e => e.Id == t.Id));
foreach (var item in toDelete)
@@ -506,6 +511,8 @@ namespace PARR.API.Controllers.V1
#endregion
}
}*/
#endregion
}
private static JobRelationshipFilter CreateRelationshipFilter(Guid fieldId, bool isParent, bool isFullMatch, bool isInverse, string valueMask)
@@ -636,6 +643,18 @@ namespace PARR.API.Controllers.V1
return true;
}
/// <summary>
/// Получить кол-во шаблонов в Job
/// </summary>
/// <param name="jobId"></param>
/// <returns></returns>
private async Task<int> GetCountTemplatesAsync(Guid jobId)
{
// Получаем только шаблоны в статусе used
return await templateService.Get().CountAsync(t => t.JobId == jobId && t.StatusTypeId == TemplateStatusTypeEnum.Used);
}
}
@@ -647,5 +666,4 @@ namespace PARR.API.Controllers.V1
}
}

View File

@@ -72,7 +72,9 @@ namespace PARR.API.Controllers.V1
IQueryable<JobGroup> query = groupService.Get()
.Include(t => t.GroupType)
.Include(t => t.GroupingUnitField);
.Include(t => t.GroupingUnitField)
.Include(t => t.ScheduleExcludeType)
.Include(t => t.ScheduleExcludeTypeCalendar);
query = query.OrderBy(t => t.GroupName);
@@ -111,6 +113,8 @@ namespace PARR.API.Controllers.V1
.Include(t => t.Jobs).ThenInclude(t => t.Tnk)
.Include(t => t.GroupType)
.Include(t => t.GroupingUnitField)
.Include(t => t.ScheduleExcludeType)
.Include(t => t.ScheduleExcludeTypeCalendar)
.FirstOrDefaultAsync(t => t.Id == id);
if (jobGroup == null)
@@ -148,6 +152,8 @@ namespace PARR.API.Controllers.V1
Solution = request.Solution.Trim(),
TemplateDuration = request.TemplateDuration.Trim(),
ReferenceDate = request.ReferenceDate,
ScheduleExcludeTypeId = request.ScheduleExcludeTypeId,
ScheduleExcludeTypeCalendarId = request.ScheduleExcludeTypeCalendarId
//IsAutoDistributionEnabled = request.IsAutoDistributionEnabled,
//IsAgent = request.IsAgent,
//AgentName = request.AgentName,
@@ -175,6 +181,8 @@ namespace PARR.API.Controllers.V1
var createdJobGroup = await groupService.Get().Include(t => t.Jobs).ThenInclude(t => t.Tnk)
.Include(t => t.GroupType)
.Include(t => t.GroupingUnitField)
.Include(t => t.ScheduleExcludeType)
.Include(t => t.ScheduleExcludeTypeCalendar)
.FirstAsync(t => t.Id == jobGroup.Id);
var locationUri = uriService.GetUri(ApiRoutes.JobGroup.Get, ApiRoutes.JobGroup.getParam, createdJobGroup.Id);
@@ -220,6 +228,8 @@ namespace PARR.API.Controllers.V1
orig.Solution = request.Solution.Trim();
orig.TemplateDuration = request.TemplateDuration.Trim();
orig.ReferenceDate = request.ReferenceDate;
orig.ScheduleExcludeTypeId = request.ScheduleExcludeTypeId;
orig.ScheduleExcludeTypeCalendarId = request.ScheduleExcludeTypeCalendarId;
//orig.IsAutoDistributionEnabled = request.IsAutoDistributionEnabled;
//orig.IsAgent = request.IsAgent;
//orig.AgentName = request.AgentName;
@@ -273,6 +283,8 @@ namespace PARR.API.Controllers.V1
.ThenInclude(t => t.Tnk)
.Include(t => t.GroupType)
.Include(t => t.GroupingUnitField)
.Include(t => t.ScheduleExcludeType)
.Include(t => t.ScheduleExcludeTypeCalendar)
.FirstAsync(t => t.Id == orig.Id);
var response = mapper.Map<JobGroupResponse>(updatedJobGroup);

View File

@@ -0,0 +1,52 @@
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
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.Constants;
using PARR.DAL.Services.Interfaces.Schedule;
namespace PARR.API.Controllers.V1
{
/// <summary>
/// Расписание регламентной работы, исключение - Календарь
/// </summary>
[Authorize(Roles = ParrRoles.Administrator.Role)]
public class ScheduleExcludeTypeCalendarController : BaseApiController
{
private readonly IMapper mapper;
private readonly IScheduleExcludeTypeCalendarService scheduleExcludeTypeCalendarService;
public ScheduleExcludeTypeCalendarController(
IMapper mapper,
IScheduleExcludeTypeCalendarService scheduleExcludeTypeCalendarService
)
{
this.mapper = mapper;
this.scheduleExcludeTypeCalendarService = scheduleExcludeTypeCalendarService;
}
/// <summary>
/// Получить список календарей исключений для расписания РР
/// </summary>
/// <returns></returns>
[HttpGet(ApiRoutes.ScheduleExcludeTypeCalendar.GetAll)]
public async Task<IActionResult> GetAll()
{
var query = scheduleExcludeTypeCalendarService.Get().OrderBy(t => t.Title);
var calendars = await query.ToListAsync();
if (!calendars.Any())
return NoContent();
var response = mapper.Map<List<ScheduleExcludeTypeCalendarResponse>>(calendars);
return Ok(new Response<List<ScheduleExcludeTypeCalendarResponse>>(response, true));
}
}
}

View File

@@ -0,0 +1,53 @@
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
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.Constants;
using PARR.DAL.Services.Interfaces.Schedule;
namespace PARR.API.Controllers.V1
{
/// <summary>
/// Расписание регламентной работы - Тип исключения
/// </summary>
[Authorize(Roles = ParrRoles.Administrator.Role)]
public class ScheduleExcludeTypeController : BaseApiController
{
private readonly IMapper mapper;
private readonly IScheduleExcludeTypeService scheduleExcludeTypeService;
public ScheduleExcludeTypeController(
IMapper mapper,
IScheduleExcludeTypeService scheduleExcludeTypeService
)
{
this.mapper = mapper;
this.scheduleExcludeTypeService = scheduleExcludeTypeService;
}
/// <summary>
/// Получить список типов исключений для расписания РР
/// </summary>
/// <returns></returns>
[HttpGet(ApiRoutes.ScheduleExcludeType.GetAll)]
public async Task<IActionResult> GetAll()
{
var query = scheduleExcludeTypeService.Get().OrderBy(t => t.Title);
var types = await query.ToListAsync();
if (!types.Any())
return NoContent();
var response = mapper.Map<List<ScheduleExcludeTypeResponse>>(types);
return Ok(new Response<List<ScheduleExcludeTypeResponse>>(response, true));
}
}
}

View File

@@ -66,6 +66,8 @@ namespace PARR.API.Controllers.V1
.Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus)
.Include(t => t.Orders)
.Include(t => t.StatusType)
.Include(t => t.Job).ThenInclude(t => t.Group).ThenInclude(t => t.ScheduleExcludeType)
.Include(t => t.Job).ThenInclude(t => t.Group).ThenInclude(t => t.ScheduleExcludeTypeCalendar)
.OrderBy(t => t.Name)
.AsSplitQuery();
@@ -125,6 +127,8 @@ namespace PARR.API.Controllers.V1
.Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus)
.Include(t => t.Orders)
.Include(t => t.StatusType)
.Include(t => t.Job).ThenInclude(t => t.Group).ThenInclude(t => t.ScheduleExcludeType)
.Include(t => t.Job).ThenInclude(t => t.Group).ThenInclude(t => t.ScheduleExcludeTypeCalendar)
.AsSplitQuery()
.FirstOrDefaultAsync(t => t.Id == id);
@@ -156,6 +160,8 @@ namespace PARR.API.Controllers.V1
.Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus)
.Include(t => t.Orders)
.Include(t => t.StatusType)
.Include(t => t.Job).ThenInclude(t => t.Group).ThenInclude(t => t.ScheduleExcludeType)
.Include(t => t.Job).ThenInclude(t => t.Group).ThenInclude(t => t.ScheduleExcludeTypeCalendar)
.AsSplitQuery()
.FirstOrDefaultAsync(t => t.Id == id);
@@ -189,6 +195,8 @@ namespace PARR.API.Controllers.V1
.Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus)
.Include(t => t.Orders)
.Include(t => t.StatusType)
.Include(t => t.Job).ThenInclude(t => t.Group).ThenInclude(t => t.ScheduleExcludeType)
.Include(t => t.Job).ThenInclude(t => t.Group).ThenInclude(t => t.ScheduleExcludeTypeCalendar)
.AsSplitQuery()
.FirstOrDefaultAsync(t => t.Id == id);