forked from ddrilling/AsbCloudServer
Валидация данных wellOperation перед вставкой, удалением, импортом...
This commit is contained in:
parent
38cbbe4109
commit
6738a30592
@ -114,5 +114,20 @@ namespace AsbCloudApp.Repositories
|
|||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
|
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// Валидация данных
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wellOperations"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool Validate(IEnumerable<WellOperationDto> wellOperations);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Валидация данных (проверка с базой)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wellOperations"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<bool> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperations, CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
}
|
}
|
@ -50,7 +50,7 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result = categories
|
var result = categories
|
||||||
.OrderBy(o => o.Name)
|
.OrderBy(o => o.Name)
|
||||||
.Adapt<IEnumerable<WellOperationCategoryDto>>();
|
.Adapt<IEnumerable<WellOperationCategoryDto>>();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -89,14 +89,14 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task<DateTime?> GetDateLastAssosiatedPlanOperationAsync(
|
private async Task<DateTime?> GetDateLastAssosiatedPlanOperationAsync(
|
||||||
int idWell,
|
int idWell,
|
||||||
DateTime? lessThenDate,
|
DateTime? lessThenDate,
|
||||||
double timeZoneHours,
|
double timeZoneHours,
|
||||||
CancellationToken token)
|
CancellationToken token)
|
||||||
{
|
{
|
||||||
if (lessThenDate is null)
|
if (lessThenDate is null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var currentDateOffset = lessThenDate.Value.ToUtcDateTimeOffset(timeZoneHours);
|
var currentDateOffset = lessThenDate.Value.ToUtcDateTimeOffset(timeZoneHours);
|
||||||
var timeZoneOffset = TimeSpan.FromHours(timeZoneHours);
|
var timeZoneOffset = TimeSpan.FromHours(timeZoneHours);
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
public async Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken)
|
public async Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var timezone = wellService.GetTimezone(idWell);
|
var timezone = wellService.GetTimezone(idWell);
|
||||||
|
|
||||||
var query = db.WellOperations.Where(o => o.IdWell == idWell && o.IdType == idType);
|
var query = db.WellOperations.Where(o => o.IdWell == idWell && o.IdType == idType);
|
||||||
|
|
||||||
if (!await query.AnyAsync(cancellationToken))
|
if (!await query.AnyAsync(cancellationToken))
|
||||||
@ -195,7 +195,7 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
|
|
||||||
var minDate = await query.MinAsync(o => o.DateStart, cancellationToken);
|
var minDate = await query.MinAsync(o => o.DateStart, cancellationToken);
|
||||||
var maxDate = await query.MaxAsync(o => o.DateStart, cancellationToken);
|
var maxDate = await query.MaxAsync(o => o.DateStart, cancellationToken);
|
||||||
|
|
||||||
return new DatesRangeDto
|
return new DatesRangeDto
|
||||||
{
|
{
|
||||||
From = minDate.ToRemoteDateTime(timezone.Hours),
|
From = minDate.ToRemoteDateTime(timezone.Hours),
|
||||||
@ -306,12 +306,13 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
DeltaDepth = g.Sum(o => o.DurationDepth),
|
DeltaDepth = g.Sum(o => o.DurationDepth),
|
||||||
IdParent = parentRelationDictionary[g.Key].IdParent
|
IdParent = parentRelationDictionary[g.Key].IdParent
|
||||||
});
|
});
|
||||||
|
|
||||||
while (dtos.All(x => x.IdParent != null))
|
while (dtos.All(x => x.IdParent != null))
|
||||||
{
|
{
|
||||||
dtos = dtos
|
dtos = dtos
|
||||||
.GroupBy(o => o.IdParent!)
|
.GroupBy(o => o.IdParent!)
|
||||||
.Select(g => {
|
.Select(g =>
|
||||||
|
{
|
||||||
var idCategory = g.Key ?? int.MinValue;
|
var idCategory = g.Key ?? int.MinValue;
|
||||||
var category = parentRelationDictionary.GetValueOrDefault(idCategory);
|
var category = parentRelationDictionary.GetValueOrDefault(idCategory);
|
||||||
var newDto = new WellGroupOpertionDto
|
var newDto = new WellGroupOpertionDto
|
||||||
@ -330,6 +331,58 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperationDtos, CancellationToken token)
|
||||||
|
{
|
||||||
|
var firstOperation = wellOperationDtos
|
||||||
|
.FirstOrDefault();
|
||||||
|
if (firstOperation is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var request = new WellOperationRequest()
|
||||||
|
{
|
||||||
|
IdWell = firstOperation.IdWell,
|
||||||
|
OperationType = firstOperation.IdType,
|
||||||
|
};
|
||||||
|
|
||||||
|
var operationWithMaxDateStart = await BuildQuery(request)
|
||||||
|
.OrderByDescending(o => o.DateStart)
|
||||||
|
.FirstOrDefaultAsync(token);
|
||||||
|
|
||||||
|
if (operationWithMaxDateStart is null)
|
||||||
|
return Validate(wellOperationDtos);
|
||||||
|
|
||||||
|
var maxOperationDateStart = operationWithMaxDateStart.DateStart;
|
||||||
|
foreach (var dto in wellOperationDtos)
|
||||||
|
{
|
||||||
|
var currentOperationDateStart = dto.DateStart.ToUniversalTime();
|
||||||
|
if (maxOperationDateStart!.AddMonths(3) < currentOperationDateStart)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
maxOperationDateStart = currentOperationDateStart;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Validate(IEnumerable<WellOperationDto> wellOperationDtos)
|
||||||
|
{
|
||||||
|
var firstOperation = wellOperationDtos
|
||||||
|
.FirstOrDefault();
|
||||||
|
if (firstOperation is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var maxOperationDateStart = firstOperation.DateStart.ToUniversalTime();
|
||||||
|
|
||||||
|
foreach (var dto in wellOperationDtos)
|
||||||
|
{
|
||||||
|
var currentOperationDateStart = dto.DateStart.ToUniversalTime();
|
||||||
|
if (maxOperationDateStart.AddMonths(3) < currentOperationDateStart)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
maxOperationDateStart = currentOperationDateStart;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task<int> InsertRangeAsync(
|
public async Task<int> InsertRangeAsync(
|
||||||
IEnumerable<WellOperationDto> wellOperationDtos,
|
IEnumerable<WellOperationDto> wellOperationDtos,
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.WellOperationImport;
|
||||||
|
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudApp.Services.WellOperationImport;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudInfrastructure;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -12,12 +18,6 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data.WellOperationImport;
|
|
||||||
using AsbCloudApp.Services.WellOperationImport;
|
|
||||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using AsbCloudInfrastructure;
|
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Controllers
|
namespace AsbCloudWebApi.Controllers
|
||||||
{
|
{
|
||||||
@ -39,8 +39,8 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
private readonly IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto> wellOperationGazpromKhantosExcelParser;
|
private readonly IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto> wellOperationGazpromKhantosExcelParser;
|
||||||
private readonly IUserRepository userRepository;
|
private readonly IUserRepository userRepository;
|
||||||
|
|
||||||
public WellOperationController(IWellOperationRepository operationRepository,
|
public WellOperationController(IWellOperationRepository operationRepository,
|
||||||
IWellService wellService,
|
IWellService wellService,
|
||||||
IWellOperationImportTemplateService wellOperationImportTemplateService,
|
IWellOperationImportTemplateService wellOperationImportTemplateService,
|
||||||
IWellOperationExportService wellOperationExportService,
|
IWellOperationExportService wellOperationExportService,
|
||||||
IWellOperationImportService wellOperationImportService,
|
IWellOperationImportService wellOperationImportService,
|
||||||
@ -231,12 +231,15 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
|
|
||||||
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
|
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
|
||||||
return Forbid();
|
return Forbid();
|
||||||
|
|
||||||
wellOperation.IdWell = idWell;
|
wellOperation.IdWell = idWell;
|
||||||
wellOperation.LastUpdateDate = DateTimeOffset.UtcNow;
|
wellOperation.LastUpdateDate = DateTimeOffset.UtcNow;
|
||||||
wellOperation.IdUser = User.GetUserId();
|
wellOperation.IdUser = User.GetUserId();
|
||||||
wellOperation.IdType = idType;
|
wellOperation.IdType = idType;
|
||||||
|
|
||||||
|
if (!await operationRepository.ValidateWithDbAsync(new[] { wellOperation }, cancellationToken))
|
||||||
|
return this.ValidationBadRequest(nameof(wellOperation), "The date difference between the operations is more than 3 months");
|
||||||
|
|
||||||
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
|
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
@ -278,7 +281,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
|
|
||||||
await operationRepository.DeleteAsync(existingOperations.Select(o => o.Id), cancellationToken);
|
await operationRepository.DeleteAsync(existingOperations.Select(o => o.Id), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var wellOperation in wellOperations)
|
foreach (var wellOperation in wellOperations)
|
||||||
{
|
{
|
||||||
wellOperation.IdWell = idWell;
|
wellOperation.IdWell = idWell;
|
||||||
@ -287,11 +290,31 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
wellOperation.IdType = idType;
|
wellOperation.IdType = idType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!await Validate(wellOperations, deleteBeforeInsert, cancellationToken))
|
||||||
|
return this.ValidationBadRequest(nameof(wellOperations), "The date difference between the operations is more than 3 months");
|
||||||
|
|
||||||
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
|
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Валидация данных перед вставкой / обновлением / импортом
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wellOperations"></param>
|
||||||
|
/// <param name="deleteBeforeInsert"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task<bool> Validate(IEnumerable<WellOperationDto> wellOperations, bool deleteBeforeInsert, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (deleteBeforeInsert)
|
||||||
|
return operationRepository.Validate(wellOperations);
|
||||||
|
else
|
||||||
|
return await operationRepository.ValidateWithDbAsync(wellOperations, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Обновляет выбранную операцию на скважине
|
/// Обновляет выбранную операцию на скважине
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -308,7 +331,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
{
|
{
|
||||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||||
return Forbid();
|
return Forbid();
|
||||||
|
|
||||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||||
return Forbid();
|
return Forbid();
|
||||||
|
|
||||||
@ -317,6 +340,9 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
value.LastUpdateDate = DateTimeOffset.UtcNow;
|
value.LastUpdateDate = DateTimeOffset.UtcNow;
|
||||||
value.IdUser = User.GetUserId();
|
value.IdUser = User.GetUserId();
|
||||||
|
|
||||||
|
if (!await operationRepository.ValidateWithDbAsync(new[] { value }, token))
|
||||||
|
return this.ValidationBadRequest(nameof(value), "The date difference between the operations is more than 3 months");
|
||||||
|
|
||||||
var result = await operationRepository.UpdateAsync(value, token)
|
var result = await operationRepository.UpdateAsync(value, token)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
@ -336,7 +362,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
{
|
{
|
||||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||||
return Forbid();
|
return Forbid();
|
||||||
|
|
||||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||||
return Forbid();
|
return Forbid();
|
||||||
|
|
||||||
@ -373,7 +399,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
deleteBeforeInsert,
|
deleteBeforeInsert,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Импорт плановых операций из excel (xlsx) файла. Стандартный заполненный шаблон
|
/// Импорт плановых операций из excel (xlsx) файла. Стандартный заполненный шаблон
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -393,7 +419,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
{
|
{
|
||||||
IdType = WellOperation.IdOperationTypePlan
|
IdType = WellOperation.IdOperationTypePlan
|
||||||
};
|
};
|
||||||
|
|
||||||
return ImportExcelFileAsync(idWell, files, options,
|
return ImportExcelFileAsync(idWell, files, options,
|
||||||
(stream, _) => wellOperationDefaultExcelParser.Parse(stream, options),
|
(stream, _) => wellOperationDefaultExcelParser.Parse(stream, options),
|
||||||
null,
|
null,
|
||||||
@ -522,7 +548,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
return this.ValidationBadRequest(nameof(files), "Требуется xlsx файл.");
|
return this.ValidationBadRequest(nameof(files), "Требуется xlsx файл.");
|
||||||
|
|
||||||
using Stream stream = file.OpenReadStream();
|
using Stream stream = file.OpenReadStream();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var sheet = parseMethod(stream, options);
|
var sheet = parseMethod(stream, options);
|
||||||
@ -541,8 +567,8 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
//TODO: очень быстрый костыль
|
//TODO: очень быстрый костыль
|
||||||
if (deleteBeforeInsert is not null && options.IdType == WellOperation.IdOperationTypeFact)
|
if (deleteBeforeInsert is not null && options.IdType == WellOperation.IdOperationTypeFact)
|
||||||
{
|
{
|
||||||
return await InsertRangeAsync(idWell, options.IdType,
|
return await InsertRangeAsync(idWell, options.IdType,
|
||||||
deleteBeforeInsert.Value,
|
deleteBeforeInsert.Value,
|
||||||
wellOperations,
|
wellOperations,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
@ -554,21 +580,21 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
return this.ValidationBadRequest(nameof(files), ex.Message);
|
return this.ValidationBadRequest(nameof(files), ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
|
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
|
||||||
{
|
{
|
||||||
int? idCompany = User.GetCompanyId();
|
int? idCompany = User.GetCompanyId();
|
||||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||||
idWell, token).ConfigureAwait(false);
|
idWell, token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> CanUserEditWellOperationsAsync(int idWell, CancellationToken token)
|
private async Task<bool> CanUserEditWellOperationsAsync(int idWell, CancellationToken token)
|
||||||
{
|
{
|
||||||
var idUser = User.GetUserId();
|
var idUser = User.GetUserId();
|
||||||
|
|
||||||
if (!idUser.HasValue)
|
if (!idUser.HasValue)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var well = await wellService.GetOrDefaultAsync(idWell, token);
|
var well = await wellService.GetOrDefaultAsync(idWell, token);
|
||||||
|
|
||||||
if (well is null)
|
if (well is null)
|
||||||
|
Loading…
Reference in New Issue
Block a user