feat(api): в Works добавлена маска динамической генерации имени шаблона; добавлены Shortcodes; актализированы валидация, запросы,ответы; миграция БД - запрет приёма нулевых значений в маску
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
public class WorkRequest
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public required string TemplateNameMask { get; set; }
|
||||
public string? TemplateSuffix { get;set; }
|
||||
public int EsppId { get; set; }
|
||||
public Guid TnkId { get; set; }
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
public required string Name { get; set; }
|
||||
|
||||
public required string TemplateNameMask { get; set; }
|
||||
|
||||
public string? TemplateSuffix { get; set; }
|
||||
|
||||
public int EsppId { get; set; }
|
||||
|
||||
@@ -137,6 +137,7 @@ namespace PARR.API.Controllers.V1
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = request.Name.Trim(),
|
||||
TemplateNameMask = request.TemplateNameMask,
|
||||
EsppId = request.EsppId,
|
||||
TnkId = request.TnkId,
|
||||
TemplateSuffix = request.TemplateSuffix
|
||||
@@ -179,6 +180,7 @@ namespace PARR.API.Controllers.V1
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Ошибка при изменении вида работ. Не найдена работа Id: {id}" } }));
|
||||
|
||||
orig.Name = request.Name.Trim();
|
||||
orig.TemplateNameMask = request.TemplateNameMask.Trim();
|
||||
orig.EsppId = request.EsppId;
|
||||
orig.TnkId = request.TnkId;
|
||||
orig.DateModified = DateTimeOffset.UtcNow;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using FluentValidation;
|
||||
using PARR.API.Contracts.V1.Requests;
|
||||
using PARR.BLL.Services.Interfaces;
|
||||
using PARR.Constants.Shortcodes;
|
||||
using PARR.DAL.Services.Interfaces;
|
||||
|
||||
namespace PARR.API.Validators
|
||||
@@ -11,13 +13,27 @@ namespace PARR.API.Validators
|
||||
private bool? isValid = null;
|
||||
|
||||
public WorkRequestValidator(
|
||||
ITnkService tnkService
|
||||
ITnkService tnkService,
|
||||
ITemplateMaskValidator templateMaskValidator
|
||||
)
|
||||
{
|
||||
this.tnkService = tnkService;
|
||||
|
||||
RuleFor(t => t.Name).NotEmpty().NotNull();
|
||||
|
||||
RuleFor(t => t.TemplateNameMask)
|
||||
.NotEmpty()
|
||||
.NotNull();
|
||||
|
||||
RuleFor(t => t.TemplateNameMask)
|
||||
.Must((entity, value, c) => templateMaskValidator
|
||||
.IsValid(entity.TemplateNameMask))
|
||||
.WithMessage($"Неверно указана маска имени шаблонов. Обязательными условиями являются" +
|
||||
$" наличие кодового слова \"ПАРР\" и обязательное использование динамической составляющей" +
|
||||
$" %ЭК%. Доступные значения динамических составляющих:" +
|
||||
$" {string.Join(", ", Shortcodes.GetAll().Select(sc => sc.Name + " - " + sc.Description))}"
|
||||
);
|
||||
|
||||
RuleFor(t => t.EsppId).NotEmpty().NotNull().WithMessage("EsppId не может быть пустым");
|
||||
|
||||
RuleFor(t => t.TnkId).NotEmpty().NotNull();
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace PARR.BLL
|
||||
services.AddTransient<ITransformService, TransformService>();
|
||||
services.AddTransient<IIntervalService, IntervalService>();
|
||||
services.AddTransient<ICalendarService, CalendarService>();
|
||||
services.AddTransient<ITemplateMaskValidator, TemplateMaskValidator>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
43
PARR.BLL/Services/Implementations/TemplateMaskValidator.cs
Normal file
43
PARR.BLL/Services/Implementations/TemplateMaskValidator.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using PARR.BLL.Services.Interfaces;
|
||||
using PARR.Constants.Shortcodes;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace PARR.BLL.Services.Implementations
|
||||
{
|
||||
internal class TemplateMaskValidator : ITemplateMaskValidator
|
||||
{
|
||||
public bool IsValid(string mask)
|
||||
{
|
||||
if (!mask.Contains("ПАРР"))
|
||||
return false;
|
||||
|
||||
var shortcodePattern = "%[^%\\s]+%";
|
||||
var shortcodesInMask = Regex.Matches(mask, shortcodePattern).ToList();
|
||||
|
||||
if (shortcodesInMask.Count() == 0)
|
||||
return false;
|
||||
|
||||
var validShortcodes = GetShortcodesNames();
|
||||
|
||||
foreach (var shortcode in shortcodesInMask)
|
||||
{
|
||||
if (!validShortcodes.Contains(shortcode.ToString().ToUpper()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<string> GetShortcodesNames()
|
||||
{
|
||||
var result = new List<string>();
|
||||
var shortcodes = Enum.GetValues(typeof(ShortcodeEnum)).Cast<ShortcodeEnum>();
|
||||
foreach (var item in shortcodes)
|
||||
{
|
||||
result.Add(Shortcodes.GetShortcodeName(item).ToUpper());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
PARR.BLL/Services/Interfaces/ITemplateMaskValidator.cs
Normal file
13
PARR.BLL/Services/Interfaces/ITemplateMaskValidator.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PARR.BLL.Services.Interfaces
|
||||
{
|
||||
public interface ITemplateMaskValidator
|
||||
{
|
||||
bool IsValid(string mask);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
public enum ShortcodeEnum
|
||||
{
|
||||
EK,
|
||||
ZO
|
||||
ZO,
|
||||
Work
|
||||
//!!!Не забыть добавить в справочник имен (ShortcodeName) строковое значение
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using System.Data.Common;
|
||||
|
||||
namespace PARR.Constants.Shortcodes
|
||||
namespace PARR.Constants.Shortcodes
|
||||
{
|
||||
public static class Shortcodes
|
||||
{
|
||||
private static readonly List<ShortcodeItem> ShortcodesList = new List<ShortcodeItem>()
|
||||
{
|
||||
new ShortcodeItem { ShortcodeEnum = ShortcodeEnum.EK, Name = "%ЭК%", Description = "Элемент конфигурации"},
|
||||
new ShortcodeItem { ShortcodeEnum = ShortcodeEnum.ZO, Name = "%ЗО%", Description = "Зона ответственности"}
|
||||
new ShortcodeItem { ShortcodeEnum = ShortcodeEnum.ZO, Name = "%ЗО%", Description = "Зона ответственности"},
|
||||
new ShortcodeItem { ShortcodeEnum = ShortcodeEnum.Work, Name = "%РАБОТА%", Description = "Наименование работ"}
|
||||
|
||||
};
|
||||
|
||||
@@ -16,5 +15,9 @@ namespace PARR.Constants.Shortcodes
|
||||
return ShortcodesList.First(s => s.ShortcodeEnum == shortcode).Name;
|
||||
}
|
||||
|
||||
public static List<ShortcodeItem> GetAll()
|
||||
{
|
||||
return ShortcodesList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3247
PARR.DAL/Migrations/20250417063402_tblWorksClmnTemplateNameMaskIsNotNull.Designer.cs
generated
Normal file
3247
PARR.DAL/Migrations/20250417063402_tblWorksClmnTemplateNameMaskIsNotNull.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace PARR.DAL.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class tblWorksClmnTemplateNameMaskIsNotNull : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "TemplateNameMask",
|
||||
table: "Works",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text",
|
||||
oldNullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "TemplateNameMask",
|
||||
table: "Works",
|
||||
type: "text",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2611,6 +2611,7 @@ namespace PARR.DAL.Migrations
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("TemplateNameMask")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("TemplateSuffix")
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace PARR.DAL.Models
|
||||
/// <summary>
|
||||
/// Маска для динамического формирования имени шаблона
|
||||
/// </summary>
|
||||
public string? TemplateNameMask { get; set; }
|
||||
public required string TemplateNameMask { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Короткое имя, для формирования имени шаблона
|
||||
|
||||
@@ -100,7 +100,8 @@ namespace PARR.MockData.Services
|
||||
DateCreated = DateTimeOffset.UtcNow,
|
||||
Name = "Прочее(работы)",
|
||||
EsppId = 292917,
|
||||
TnkId = tnk.Id
|
||||
TnkId = tnk.Id,
|
||||
TemplateNameMask= "%ЗО%-ЭИТИ-ПТК-ПАРР__%ЭК%__%РАБОТА%"
|
||||
};
|
||||
if (!await workService.CreateAsync(work) || !await workService.CommitAsync())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user