WellOperationRepository refactor ValidateWithDbAsync and Validate

This commit is contained in:
ngfrolov 2024-01-25 16:47:04 +05:00
parent a8e2ea9632
commit 672f78fca9
Signed by untrusted user who does not match committer: ng.frolov
GPG Key ID: E99907A0357B29A7
4 changed files with 56 additions and 30 deletions

View File

@ -129,6 +129,6 @@ namespace AsbCloudApp.Repositories
/// <param name="wellOperations"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
IEnumerable<ValidationResult> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperations, CancellationToken cancellationToken);
Task<IEnumerable<ValidationResult>> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperations, CancellationToken cancellationToken);
}
}

View File

@ -334,12 +334,13 @@ public class WellOperationRepository : IWellOperationRepository
return dtos;
}
public IEnumerable<ValidationResult> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperationDtos, CancellationToken token)
public async Task<IEnumerable<ValidationResult>> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperationDtos, CancellationToken token)
{
var firstOperation = wellOperationDtos
.FirstOrDefault();
if (firstOperation is null)
yield break;
return Enumerable.Empty<ValidationResult>();
var request = new WellOperationRequest()
{
@ -347,48 +348,49 @@ public class WellOperationRepository : IWellOperationRepository
OperationType = firstOperation.IdType,
};
var entities = BuildQuery(request)
var entities = await BuildQuery(request)
.AsNoTracking()
.ToArray();
.ToArrayAsync(token);
var wellOperationsUnion = entities.Union(wellOperationDtos).OrderBy(o => o.DateStart);
var results = Validate(wellOperationsUnion);
foreach ( var result in results)
yield return result;
return results;
}
public IEnumerable<ValidationResult> Validate(IEnumerable<WellOperationDto> wellOperationDtos)
{
var firstOperation = wellOperationDtos
.FirstOrDefault();
if (firstOperation is null)
var enumerator = wellOperationDtos.OrderBy(o => o.DateStart)
.GetEnumerator();
if (!enumerator.MoveNext())
yield break;
var wellOperations = wellOperationDtos.OrderBy(o => o.DateStart).ToArray();
for (var i = 1; i < wellOperations.Length; i++)
var previous = enumerator.Current;
while(enumerator.MoveNext())
{
var prevOperation = wellOperations[i - 1];
var currentOperation = wellOperations[i];
var current = enumerator.Current;
var previousDateStart = previous.DateStart.ToUniversalTime();
var currentDateStart = current.DateStart.ToUniversalTime();
var prevOperationDateStart = prevOperation.DateStart.ToUniversalTime();
var currentOperationDateStart = currentOperation.DateStart.ToUniversalTime();
var previousDateEnd = previous.DateStart.AddHours(previous.DurationHours).ToUniversalTime();
var prevOperationDateEnd = prevOperation.DateStart.AddHours(prevOperation.DurationHours).ToUniversalTime();
if (prevOperationDateStart.AddDays(Gap) < currentOperationDateStart)
if (previousDateStart.AddDays(Gap) < currentDateStart)
{
yield return new ValidationResult(
$"Разница дат между операциями не должна превышать 90 дней",
new[] { nameof(wellOperations) });
"Разница дат между операциями не должна превышать 90 дней",
new[] { nameof(wellOperationDtos) });
}
if (prevOperationDateEnd > currentOperationDateStart)
if (previousDateEnd > currentDateStart)
{
yield return new ValidationResult(
$"Предыдущая операция не завершена",
new[] { nameof(wellOperations) });
"Предыдущая операция не завершена",
new[] { nameof(wellOperationDtos) });
}
previous = current;
}
}

View File

@ -237,9 +237,9 @@ namespace AsbCloudWebApi.Controllers
wellOperation.IdUser = User.GetUserId();
wellOperation.IdType = idType;
var validationResult = operationRepository.ValidateWithDbAsync(new[] { wellOperation }, cancellationToken);
var validationResult = awaitoperationRepository.ValidateWithDbAsync(new[] { wellOperation }, cancellationToken);
if(validationResult.Any())
return this.ValidationBadRequest(nameof(wellOperation), "The date difference between the operations is more than 3 months");
return this.ValidationBadRequest(validationResult);
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
@ -294,7 +294,7 @@ namespace AsbCloudWebApi.Controllers
var validationResult = Validate(wellOperations, deleteBeforeInsert, cancellationToken);
if (validationResult.Any())
return this.ValidationBadRequest(nameof(wellOperations), "The date difference between the operations is more than 3 months");
return this.ValidationBadRequest(validationResult);
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
@ -314,7 +314,7 @@ namespace AsbCloudWebApi.Controllers
if (deleteBeforeInsert)
return operationRepository.Validate(wellOperations);
else
return operationRepository.ValidateWithDbAsync(wellOperations, cancellationToken);
return await operationRepository.ValidateWithDbAsync(wellOperations, cancellationToken);
}
/// <summary>
@ -342,9 +342,9 @@ namespace AsbCloudWebApi.Controllers
value.LastUpdateDate = DateTimeOffset.UtcNow;
value.IdUser = User.GetUserId();
var validationResult = operationRepository.ValidateWithDbAsync(new[] { value }, token);
var validationResult = await operationRepository.ValidateWithDbAsync(new[] { value }, token);
if (validationResult.Any())
return this.ValidationBadRequest(nameof(value), "The date difference between the operations is more than 3 months");
return this.ValidationBadRequest(validationResult);
var result = await operationRepository.UpdateAsync(value, token)
.ConfigureAwait(false);

View File

@ -3,6 +3,8 @@ using AsbCloudWebApi.Converters;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Security.Claims;
namespace Microsoft.AspNetCore.Mvc
@ -53,6 +55,28 @@ namespace Microsoft.AspNetCore.Mvc
return controller.BadRequest(problem);
}
/// <summary>
/// <para>
/// Returns BadRequest with ValidationProblemDetails as body
/// </para>
/// <para>
/// Используйте этот метод только если валидацию нельзя сделать через
/// атрибуты валидации или IValidatableObject модели.
/// </para>
/// </summary>
/// <param name="controller"></param>
/// <param name="paramName"></param>
/// <param name="error"></param>
/// <returns></returns>
public static BadRequestObjectResult ValidationBadRequest(this ControllerBase controller, IEnumerable<ValidationResult> validationResults)
{
var errors = validationResults
.SelectMany(e => e.MemberNames.Select(name=> new { name, e.ErrorMessage }))
.ToDictionary(e => e.name, e => new[] { e.ErrorMessage ?? string.Empty });
var problem = new ValidationProblemDetails(errors);
return controller.BadRequest(problem);
}
public static MvcOptions UseDateOnlyTimeOnlyStringConverters(this MvcOptions options)
{
TypeDescriptor.AddAttributes(typeof(DateOnly), new TypeConverterAttribute(typeof(DateOnlyTypeConverter)));