feat(dal,domain): Таблицы для JobGroup фильтров.

This commit is contained in:
Mikhail Trubnikov
2026-06-15 16:56:23 +10:00
parent 1fb5cbd2e8
commit 108eb05853
49 changed files with 4997 additions and 190 deletions

View File

@@ -0,0 +1,197 @@
using Microsoft.EntityFrameworkCore;
using PARR.Domain.Constants;
using PARR.Domain.Entities.Base;
using PARR.Domain.Entities.Schedule;
using PARR.Domain.Entities.Unit;
using PARR.Domain.Settings;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PARR.Domain.Entities.JobGroupEntities
{
[Table("Groups", Schema = DatabaseSchemas.JobGroup)]
[Comment("Таблица описания групп работ, для реализации зонтиков")]
public class JobGroup : IBaseEntity
{
[Key]
public Guid Id { get; set; }
public DateTimeOffset DateCreated { get; set; }
public DateTimeOffset? DateModified { get; set; }
/// <summary>
/// Наименование работ для интерфеса в ПАРР
/// </summary>
public required string GroupName { get; set; }
///// <summary>
///// Связана ли работа с групповыми ЭК(зонтами)
///// </summary>
//public bool? IsUmbrella { get; set; }
/// <summary>
/// Поле Короткое описания шаблона АСУ ЕСПП
/// </summary>
public required string ShortDescription { get; set; }
/// <summary>
/// Поле Подробное описания шаблона АСУ ЕСПП
/// </summary>
private string _fullDescription = string.Empty;
public required string FullDescription
{
get
{
//В полное описание подставляем префикс, для дальнейшего поиска наряда
return $"{_fullDescription}\r\n{PrefixSettings.PrefixWithoutVariable}";
}
set
{
//удаляем префикс, если он есть
//_fullDescription = value.Replace($"\r\n{PrefixSettings.PrefixWithoutVariable}", string.Empty);
_fullDescription = value.Replace($"{PrefixSettings.PrefixWithoutVariable}", string.Empty).TrimEnd();
}
}
//public required string FullDescription { get; set; }
/// <summary>
/// Поле Решение описания шаблона АСУ ЕСПП
/// </summary>
public required string Solution { get; set; }
/// <summary>
/// Поле Длительность описания шаблона АСУ ЕСПП
/// </summary>
public required string TemplateDuration { get; set; }
/// <summary>
/// TemplateDuration в формате TimeSpan
/// </summary>
public TimeSpan? TemplateDurationTimeSpan
{
get
{
try
{
//ЕСПП кривоногие, они почему-то таймспан пишут так "7 00:00:00", а правильно так: "7:00:00:00"
var durationWithTimeSpanFormat = TemplateDuration.Replace(" ", ":");
return TimeSpan.Parse(durationWithTimeSpanFormat);
}
catch
{
return null;
}
}
}
/// <summary>
/// Дата начала работ или дата для отсчёта периода следующего выполнения
/// </summary>
public DateTimeOffset ReferenceDate { get; set; }
/// <summary>
/// Смещение часового пояса пользователя в минутах относительно UTC на момент ReferenceDate
/// </summary>
[Comment("Смещение часового пояса пользователя в минутах относительно UTC на момент ReferenceDate")]
public int? UserTimeZoneOffsetMinutes { get; set; }
/// <summary>
/// Смещение часового пояса пользователя относительно UTC на момент ReferenceDate, рассчитывается из поля UserTimeZoneOffsetMinutes
/// </summary>
[NotMapped]
public TimeSpan? UserTimeZoneOffset =>
UserTimeZoneOffsetMinutes.HasValue
? TimeSpan.FromMinutes(UserTimeZoneOffsetMinutes.Value)
: null;
/// <summary>
/// Использовать таймзону рабочей группы ответственного за ЭК шаблона
/// </summary>
public bool IsResponseAreaTimezone { get; set; } = false;
/// <summary>
/// Включить автораспределение
/// </summary>
public bool IsAutoDistributionEnabled { get; set; }
/// <summary>
/// Выполняет агент
/// </summary>
public bool IsAgent { get; set; }
/// <summary>
/// Какое-то имя которое мы передаем агенту, пока непонятно что это такое.
/// </summary>
public string? AgentName { get; set; }
/// <summary>
/// Сколько времени ожидать выполнение скрипта агентом (секунд)
/// </summary>
public int? AgentTimeOutSec { get; set; }
/// <summary>
/// Скрипт для автоматического выполнения
/// </summary>
public string? AgentScript { get; set; }
/// <summary>
/// Тип группы
/// </summary>
public Guid GroupTypeId { get; set; }
/// <summary>
/// Если тип группы - "Сгруппированный", то это поле обязательно, по нему будем группировать
/// TODO: !!!! Связь с иаблице UnitField не создавалась! Нужно это переделать и унести в отдельную таблицу
/// </summary>
public Guid? GroupingUnitFieldId { get; set; }
/// <summary>
/// Группировать по ответственному за ЭК.
/// Если тип группы - "Сгруппированный", то можно менять значение этого поля, в иных случаях - null
/// TODO: По хорошему вынести это в другую таблицу, так как это касается только групповых работ
/// </summary>
public bool? IsGroupByResponsible { get; set; }
/// <summary>
/// Расписание регламентной работы - Тип исключения
/// </summary>
public Guid ScheduleExcludeTypeId { get; set; }
/// <summary>
/// Расписание регламентной работы, исключение - Календарь
/// </summary>
public Guid? ScheduleExcludeTypeCalendarId { get; set; }
/// <summary>
/// Поле по которому группируется (!!!отключено каскадное удаление!!!)
/// </summary>
[ForeignKey(nameof(GroupingUnitFieldId))]
public UnitField? GroupingUnitField { get; set; }
[ForeignKey(nameof(GroupTypeId))]
public JobGroupType? GroupType { get; set; }
public ICollection<Job.Job> Jobs { get; set; } = new HashSet<Job.Job>();
public ICollection<EsppSchValue> EsppSchValues { get; set; } = new HashSet<EsppSchValue>();
[ForeignKey(nameof(ScheduleExcludeTypeId))]
public ScheduleExcludeType? ScheduleExcludeType { get; set; }
[ForeignKey(nameof(ScheduleExcludeTypeCalendarId))]
public ScheduleExcludeTypeCalendar? ScheduleExcludeTypeCalendar { get; set; }
public JobGroupDistributionConfig? DistributionConfig { get; set; }
public JobGroupAutoControl? AutoControl { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore;
using PARR.Domain.Constants;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PARR.Domain.Entities.JobGroupEntities
{
[Table("AutoControls", Schema = DatabaseSchemas.JobGroup)]
[Comment("Таблица управления автоконтролем для группы работ")]
public class JobGroupAutoControl
{
[Key]
public Guid JobGroupId { get; set; }
/// <summary>
/// Включен автоконтроль
/// </summary>
public bool IsEnable { get; set; } = false;
/// <summary>
/// Статус шаблона в момент привязки или создания нового шаблона к Job
/// </summary>
public bool InitUsedTemplateState { get; set; } = false;
/// <summary>
/// Статус расписания в момент привязки или создания нового шаблона к Job
/// </summary>
public bool InitUsedScheduleState { get; set; } = false;
[ForeignKey(nameof(JobGroupId))]
public JobGroup? JobGroup { get; set; }
}
}

View File

@@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore;
using PARR.Domain.Constants;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PARR.Domain.Entities.JobGroupEntities
{
/// <summary>
/// Настройки автораспределения для JobGroup
/// </summary>
[Table("GroupDistributionConfigs", Schema = DatabaseSchemas.JobGroup)]
[Comment("Настройки автораспределения для группы работ")]
public class JobGroupDistributionConfig
{
[Key]
public Guid GroupId { get; set; }
public Guid DistributionPeriodId { get; set; }
/// <summary>
/// Исключать выходные и праздничные дни
/// </summary>
public bool IsExcludeWeekends { get; set; }
/// <summary>
/// Группировать по рабочей группе
/// </summary>
public bool IsGroupingByWorkGroup { get; set; }
[ForeignKey(nameof(GroupId))]
public JobGroup? Group { get; set; }
[ForeignKey(nameof(DistributionPeriodId))]
public DistributionPeriod? DistributionPeriod { get; set; }
}
}

View File

@@ -0,0 +1,39 @@
using Microsoft.EntityFrameworkCore;
using PARR.Domain.Constants;
using PARR.Domain.Entities.Base;
using PARR.Domain.Entities.Unit;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PARR.Domain.Entities.JobGroupEntities
{
[Table("FieldFilters", Schema = DatabaseSchemas.JobGroup)]
[Comment("Таблица описания критериев выборки аттрибутов ЭК")]
public class JobGroupFieldFilter : IBaseEntity
{
[Key]
public Guid Id { get; set; }
public DateTimeOffset DateCreated { get; set; }
[NotMapped]
public DateTimeOffset? DateModified { get; set; }
public Guid UnitFilterId { get; set; }
public Guid FieldId { get; set; }
public required string ValueMask { get; set; }
/// <summary>
/// Отсутствует
/// </summary>
public bool IsInverse { get; set; } = false;
[ForeignKey(nameof(FieldId))]
public UnitField? UnitField { get; set; }
[ForeignKey(nameof(UnitFilterId))]
public JobGroupUnitFilter? UnitFilter { get; set; }
}
}

View File

@@ -0,0 +1,51 @@
using Microsoft.EntityFrameworkCore;
using PARR.Domain.Cache.Models;
using PARR.Domain.Constants;
using PARR.Domain.Entities.Job;
using PARR.Domain.Entities.Unit;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PARR.Domain.Entities.JobGroupEntities
{
[Table("RelationshipFilters", Schema = DatabaseSchemas.JobGroup)]
[Comment("Таблица фильтров связей ЭК")]
[PrimaryKey(nameof(UnitFilterId), nameof(FieldId))]
public class JobGroupRelationshipFilter
{
public Guid UnitFilterId { get; set; }
/// <summary>
/// Родительская связь - true,
/// Дочерняя связь - false
/// </summary>
public bool IsParent { get; set; }
public Guid FieldId { get; set; }
public required string ValueMask { get; set; }
/// <summary>
/// Полное совпадение или хотябы одно
/// true - list.All()
/// false - list.Any()
/// </summary>
public bool IsFullMatch { get; set; }
/// <summary>
/// Обратный фильтр, что у связи нет таких значений
/// </summary>
public bool IsInverse { get; set; }
[ForeignKey(nameof(UnitFilterId))]
public JobGroupUnitFilter? UnitFilter { get; set; }
[ForeignKey(nameof(FieldId))]
public UnitField? UnitField { get; set; }
}
}

View File

@@ -0,0 +1,44 @@
using Microsoft.EntityFrameworkCore;
using PARR.Domain.Constants;
using PARR.Domain.Entities.Base;
using PARR.Domain.Enums;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PARR.Domain.Entities.JobGroupEntities
{
[Table("GroupTypes", Schema = DatabaseSchemas.JobGroup)]
[Comment("Таблица типов групп работ")]
public class JobGroupType : IBaseEntity
{
[Key]
public Guid Id { get; set; }
public DateTimeOffset DateCreated { get; set; }
[NotMapped]
public DateTimeOffset? DateModified { get; set; }
public required JobGroupTypesEnum Code { get; set; }
public required string Name { get; set; }
public required string Description { get; set; }
/// <summary>
/// Разрешить Job фильтры. Влияет только на интерфейс.
/// Мэтчер собирает все фильтры из группы и работ всегда.
/// </summary>
[Comment("Разрешить Job фильтры. Влияет только на интерфейс. Мэтчер собирает все фильтры из группы и работ всегда.")]
public bool IsAllowJobUnitFilter { get; set; }
/// <summary>
/// Автоконтролем управляет JobGroup? true - да JobGroup, false - Job.
/// Влияет на интерфейс и на логику работы автоконтроля.
/// </summary>
[Comment("Автоконтролем управляет JobGroup? true - да JobGroup, false - Job. Влияет на интерфейс и на логику работы автоконтроля.")]
public bool IsJobGroupAutoControl { get; set; } = false;
public ICollection<JobGroup> JobGroups { get; set; } = new HashSet<JobGroup>();
}
}

View File

@@ -0,0 +1,32 @@
using Microsoft.EntityFrameworkCore;
using PARR.Domain.Constants;
using PARR.Domain.Entities.Base;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PARR.Domain.Entities.JobGroupEntities
{
[Table("UnitFilters", Schema = DatabaseSchemas.JobGroup)]
[Comment("Таблица описания критериев выборки ЭК, описание полей в АСУ ЕСПП")]
public class JobGroupUnitFilter : IBaseEntity
{
[Key]
public Guid Id { get; set; }
public DateTimeOffset DateCreated { get; set; }
[NotMapped]
public DateTimeOffset? DateModified { get; set; }
public required string UnitFilter { get; set; }
public Guid JobGroupId { get; set; }
[ForeignKey(nameof(JobGroupId))]
public JobGroup? JobGroup { get; set; }
public ICollection<JobGroupFieldFilter> FieldFilters { get; set; } = new HashSet<JobGroupFieldFilter>();
public ICollection<JobGroupRelationshipFilter> RelationshipFilters { get; set; } = new HashSet<JobGroupRelationshipFilter>();
}
}