forked from ddrilling/AsbCloudServer
Merge branch 'feature/27526736-cache-table' of http://test.digitaldrilling.ru:8080/DDrilling/AsbCloudServer into feature/27526736-cache-table
This commit is contained in:
commit
2832a73b6c
@ -1,15 +1,18 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
|
||||||
namespace AsbCloudApp.Repositories;
|
namespace AsbCloudApp.Repositories;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Репозиторий для записей с историей
|
/// Репозиторий для записей с историей
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IChangeLogRepository<T>
|
public interface IChangeLogRepository<TDto, TRequest>
|
||||||
where T : ChangeLogAbstract
|
where TDto : ChangeLogAbstract
|
||||||
|
where TRequest : ChangeLogBaseRequest
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавление записей
|
/// Добавление записей
|
||||||
@ -18,7 +21,7 @@ public interface IChangeLogRepository<T>
|
|||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> InsertRange(int idUser, IEnumerable<T> dtos, CancellationToken token);
|
Task<int> InsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Редактирование записей
|
/// Редактирование записей
|
||||||
@ -27,7 +30,35 @@ public interface IChangeLogRepository<T>
|
|||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> UpdateRange(int idUser, IEnumerable<T> dtos, CancellationToken token);
|
Task<int> UpdateRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавляет Dto у которых id == 0, изменяет dto у которых id != 0
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idUser"></param>
|
||||||
|
/// <param name="dtos"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<int> UpdateOrInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавление записей с удалением старых (для импорта)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idUser"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<int> Clear(int idUser, TRequest request, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Очистить и добавить новые
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idUser"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="dtos"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<int> ClearAndInsertRange(int idUser, TRequest request, IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Удаление записей
|
/// Удаление записей
|
||||||
@ -38,4 +69,30 @@ public interface IChangeLogRepository<T>
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token);
|
Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение дат изменений записей
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<DateOnly>> GetDatesChange(TRequest request, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение журнала изменений
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="date">Фильтр по дате. Если null - вернет все</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<TDto>> GetChangeLog(TRequest request, DateOnly? date, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение записей по параметрам
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<TDto>> Get(TRequest request, CancellationToken token);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AsbCloudApp.Data.ProcessMapPlan;
|
|
||||||
using AsbCloudApp.Requests;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Repositories;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Общий интерфейс для РТК план с учетом истории изменений
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
public interface IProcessMapPlanBaseRepository<T>: IChangeLogRepository<T>
|
|
||||||
where T: ProcessMapPlanBaseDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Добавление записей с удалением старых (для импорта)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idUser"></param>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="dtos"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<int> ClearAndInsertRange(int idUser, int idWell, IEnumerable<T> dtos, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение дат изменений записей
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IEnumerable<DateOnly>> GetDatesChange(int idWell, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение журнала изменений
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="date"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IEnumerable<T>> GetChangeLog(int idWell, DateOnly? date, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение записей по параметрам
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="request"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IEnumerable<T>> Get(int idWell, ProcessMapPlanBaseRequest request, CancellationToken token);
|
|
||||||
}
|
|
@ -4,12 +4,14 @@ using System.Threading;
|
|||||||
using AsbCloudApp.Data.ProcessMaps;
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace AsbCloudApp.Repositories;
|
namespace AsbCloudApp.Repositories;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// РТК план
|
/// РТК план
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete]
|
||||||
public interface IProcessMapPlanRepository<TDto> : IRepositoryWellRelated<TDto>
|
public interface IProcessMapPlanRepository<TDto> : IRepositoryWellRelated<TDto>
|
||||||
where TDto : ProcessMapPlanBaseDto
|
where TDto : ProcessMapPlanBaseDto
|
||||||
{
|
{
|
||||||
|
@ -19,3 +19,36 @@ public class ProcessMapPlanBaseRequest: ChangeLogBaseRequest
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset? UpdateFrom { get; set; }
|
public DateTimeOffset? UpdateFrom { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Запрос для получения РТК план по скважине
|
||||||
|
/// </summary>
|
||||||
|
public class ProcessMapPlanBaseRequestWithWell: ProcessMapPlanBaseRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Запрос для получения РТК план по скважине
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
public ProcessMapPlanBaseRequestWithWell(int idWell)
|
||||||
|
{
|
||||||
|
IdWell = idWell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Запрос для получения РТК план по скважине
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
public ProcessMapPlanBaseRequestWithWell(ProcessMapPlanBaseRequest request, int idWell)
|
||||||
|
{
|
||||||
|
IdWell=idWell;
|
||||||
|
IdWellSectionType=request.IdWellSectionType;
|
||||||
|
UpdateFrom = request.UpdateFrom;
|
||||||
|
Moment = request.Moment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Id скважины
|
||||||
|
/// </summary>
|
||||||
|
public int IdWell { get; set; }
|
||||||
|
}
|
@ -28,7 +28,7 @@ public abstract class ChangeLogAbstract
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Очищено при импорте
|
/// Очищено при импорте
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int IdClearedOnImport = 3;
|
public const int IdCleared = 3;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ид записи
|
/// Ид записи
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
<PackageReference Include="CliWrap" Version="3.6.6" />
|
<PackageReference Include="CliWrap" Version="3.6.6" />
|
||||||
<PackageReference Include="ClosedXML" Version="0.97.0" />
|
<PackageReference Include="ClosedXML" Version="0.97.0" />
|
||||||
<PackageReference Include="itext7" Version="8.0.2" />
|
<PackageReference Include="itext7" Version="8.0.2" />
|
||||||
|
<PackageReference Include="itext7.bouncy-castle-adapter" Version="8.0.2" />
|
||||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.1.21" />
|
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.1.21" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||||
|
@ -45,6 +45,7 @@ using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
|
|||||||
using AsbCloudDb.Model.WellSections;
|
using AsbCloudDb.Model.WellSections;
|
||||||
using AsbCloudInfrastructure.Services.ProcessMaps;
|
using AsbCloudInfrastructure.Services.ProcessMaps;
|
||||||
using AsbCloudApp.Data.ProcessMapPlan;
|
using AsbCloudApp.Data.ProcessMapPlan;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure
|
namespace AsbCloudInfrastructure
|
||||||
{
|
{
|
||||||
@ -195,10 +196,10 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IOperationsStatService, OperationsStatService>();
|
services.AddTransient<IOperationsStatService, OperationsStatService>();
|
||||||
services.AddTransient<IReportService, ReportService>();
|
services.AddTransient<IReportService, ReportService>();
|
||||||
services.AddTransient<ISetpointsService, SetpointsService>();
|
services.AddTransient<ISetpointsService, SetpointsService>();
|
||||||
services.AddTransient<ITelemetryService, TelemetryService>();
|
services.AddScoped<ITelemetryService, TelemetryService>();
|
||||||
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
||||||
services.AddTransient<ITimezoneService, TimezoneService>();
|
services.AddTransient<ITimezoneService, TimezoneService>();
|
||||||
services.AddTransient<IWellService, WellService>();
|
services.AddScoped<IWellService, WellService>();
|
||||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||||
services.AddTransient<IProcessMapReportWellDrillingExportService, ProcessMapReportWellDrillingExportService>();
|
services.AddTransient<IProcessMapReportWellDrillingExportService, ProcessMapReportWellDrillingExportService>();
|
||||||
services.AddTransient<TrajectoryPlanExportService>();
|
services.AddTransient<TrajectoryPlanExportService>();
|
||||||
@ -222,7 +223,9 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IHelpPageService, HelpPageService>();
|
services.AddTransient<IHelpPageService, HelpPageService>();
|
||||||
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
||||||
|
|
||||||
services.AddTransient<IProcessMapPlanBaseRepository<ProcessMapPlanDrillingDto>, ProcessMapPlanBaseRepository<ProcessMapPlanDrillingDto, ProcessMapPlanDrilling>>();
|
services.AddTransient<
|
||||||
|
IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell>,
|
||||||
|
ProcessMapPlanBaseRepository<ProcessMapPlanDrillingDto, ProcessMapPlanDrilling>>();
|
||||||
|
|
||||||
services.AddTransient<TrajectoryService>();
|
services.AddTransient<TrajectoryService>();
|
||||||
|
|
||||||
|
288
AsbCloudInfrastructure/Repository/ChangeLogRepositoryAbstract.cs
Normal file
288
AsbCloudInfrastructure/Repository/ChangeLogRepositoryAbstract.cs
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using Mapster;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Npgsql;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Repository;
|
||||||
|
|
||||||
|
public abstract class ChangeLogRepositoryAbstract<TDto, TEntity, TRequest> : IChangeLogRepository<TDto, TRequest>
|
||||||
|
where TDto : AsbCloudApp.Data.ChangeLogAbstract
|
||||||
|
where TEntity : ChangeLogAbstract
|
||||||
|
where TRequest : ChangeLogBaseRequest
|
||||||
|
{
|
||||||
|
protected readonly IAsbCloudDbContext context;
|
||||||
|
|
||||||
|
public ChangeLogRepositoryAbstract(IAsbCloudDbContext context)
|
||||||
|
{
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> InsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = 0;
|
||||||
|
if (dtos.Any())
|
||||||
|
{
|
||||||
|
var entities = dtos.Select(Convert);
|
||||||
|
var creation = DateTimeOffset.UtcNow;
|
||||||
|
var dbSet = context.Set<TEntity>();
|
||||||
|
foreach (var entity in entities)
|
||||||
|
{
|
||||||
|
entity.Id = default;
|
||||||
|
entity.IdAuthor = idUser;
|
||||||
|
entity.Creation = creation;
|
||||||
|
entity.IdState = ChangeLogAbstract.IdStateActual;
|
||||||
|
entity.IdEditor = null;
|
||||||
|
entity.IdPrevious = null;
|
||||||
|
entity.Obsolete = null;
|
||||||
|
dbSet.Add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
result += await SaveChangesWithExceptionHandling(token);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> UpdateRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
|
{
|
||||||
|
if (dtos.Any(d => d.Id == 0))
|
||||||
|
throw new ArgumentInvalidException(nameof(dtos), "Отредактированные значения должны иметь id не 0");
|
||||||
|
|
||||||
|
if (!dtos.Any())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var updateTime = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
var ids = dtos.Select(d => d.Id);
|
||||||
|
|
||||||
|
using var transaction = context.Database.BeginTransaction();
|
||||||
|
var result = 0;
|
||||||
|
var dbSet = context
|
||||||
|
.Set<TEntity>();
|
||||||
|
|
||||||
|
var entitiesToDelete = await dbSet
|
||||||
|
.Where(e => e.Obsolete == null)
|
||||||
|
.Where(e => ids.Contains(e.Id))
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
|
var entitiesNotFound = dtos.Where(d => !entitiesToDelete.Any(e => e.Id == d.Id));
|
||||||
|
if (entitiesNotFound.Any())
|
||||||
|
{
|
||||||
|
var notFoundIds = entitiesNotFound.Select(e => e.Id);
|
||||||
|
var stringnotFoundIds = string.Join(", ", notFoundIds);
|
||||||
|
throw new ArgumentInvalidException(nameof(dtos), $"записи с id:[{stringnotFoundIds}] не найдены, или не актуальны.");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var entity in entitiesToDelete)
|
||||||
|
{
|
||||||
|
entity.IdState = ChangeLogAbstract.IdStateReplaced;
|
||||||
|
entity.Obsolete = updateTime;
|
||||||
|
entity.IdEditor = idUser;
|
||||||
|
}
|
||||||
|
result += await context.SaveChangesAsync(token);
|
||||||
|
|
||||||
|
var entitiesNew = dtos.Select(Convert);
|
||||||
|
foreach (var entity in entitiesNew)
|
||||||
|
{
|
||||||
|
entity.IdPrevious = entity.Id;
|
||||||
|
entity.Id = default;
|
||||||
|
entity.Creation = updateTime;
|
||||||
|
entity.IdAuthor = idUser;
|
||||||
|
entity.Obsolete = null;
|
||||||
|
entity.IdEditor = null;
|
||||||
|
entity.IdState = ChangeLogAbstract.IdStateActual;
|
||||||
|
dbSet.Add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
result += await SaveChangesWithExceptionHandling(token);
|
||||||
|
await transaction.CommitAsync(token);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> UpdateOrInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
|
{
|
||||||
|
var itemsToInsert = dtos.Where(e => e.Id == 0);
|
||||||
|
var itemsToUpdate = dtos.Where(e => e.Id != 0);
|
||||||
|
|
||||||
|
var result = 0;
|
||||||
|
if (itemsToInsert.Any())
|
||||||
|
result += await InsertRange(idUser, itemsToInsert, token);
|
||||||
|
|
||||||
|
if (itemsToUpdate.Any())
|
||||||
|
result += await UpdateRange(idUser, itemsToUpdate, token);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Clear(int idUser, TRequest request, CancellationToken token)
|
||||||
|
{
|
||||||
|
var updateTime = DateTimeOffset.UtcNow;
|
||||||
|
var query = BuildQuery(request);
|
||||||
|
query = query.Where(e => e.Obsolete == null);
|
||||||
|
|
||||||
|
var entitiesToDelete = await query.ToArrayAsync(token);
|
||||||
|
|
||||||
|
foreach (var entity in entitiesToDelete)
|
||||||
|
{
|
||||||
|
entity.IdState = ChangeLogAbstract.IdCleared;
|
||||||
|
entity.Obsolete = updateTime;
|
||||||
|
entity.IdEditor = idUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await SaveChangesWithExceptionHandling(token);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> ClearAndInsertRange(int idUser, TRequest request, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = 0;
|
||||||
|
var transaction = await context.Database.BeginTransactionAsync(token);
|
||||||
|
result += await Clear(idUser, request, token);
|
||||||
|
result += await InsertRange(idUser, dtos, token);
|
||||||
|
await transaction.CommitAsync(token);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token)
|
||||||
|
{
|
||||||
|
var updateTime = DateTimeOffset.UtcNow;
|
||||||
|
var query = context.Set<TEntity>()
|
||||||
|
.Where(e => ids.Contains(e.Id))
|
||||||
|
.Where(e => e.Obsolete == null);
|
||||||
|
|
||||||
|
var entitiesToDelete = await query.ToArrayAsync(token);
|
||||||
|
|
||||||
|
foreach (var entity in entitiesToDelete)
|
||||||
|
{
|
||||||
|
entity.IdState = ChangeLogAbstract.IdStateDeleted;
|
||||||
|
entity.Obsolete = updateTime;
|
||||||
|
entity.IdEditor = idUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await SaveChangesWithExceptionHandling(token);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<DateOnly>> GetDatesChange(TRequest request, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = BuildQuery(request);
|
||||||
|
|
||||||
|
var datesCreateQuery = query
|
||||||
|
.Select(e => e.Creation)
|
||||||
|
.Distinct();
|
||||||
|
|
||||||
|
var datesCreate = await datesCreateQuery.ToArrayAsync(token);
|
||||||
|
|
||||||
|
var datesUpdateQuery = query
|
||||||
|
.Where(e => e.Obsolete != null)
|
||||||
|
.Select(e => e.Obsolete!.Value)
|
||||||
|
.Distinct();
|
||||||
|
|
||||||
|
var datesUpdate = await datesUpdateQuery.ToArrayAsync(token);
|
||||||
|
|
||||||
|
TimeSpan offset = GetTimezoneOffset(request);
|
||||||
|
|
||||||
|
var dates = Enumerable.Concat(datesCreate, datesUpdate);
|
||||||
|
dates = dates.Select(date => date.ToOffset(offset));
|
||||||
|
var datesOnly = dates
|
||||||
|
.Select(d => new DateOnly(d.Year, d.Month, d.Day))
|
||||||
|
.Distinct()
|
||||||
|
.OrderBy(d => d);
|
||||||
|
|
||||||
|
return datesOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<TDto>> GetChangeLog(TRequest request, DateOnly? date, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = BuildQuery(request);
|
||||||
|
TimeSpan offset = GetTimezoneOffset(request);
|
||||||
|
|
||||||
|
if (date.HasValue)
|
||||||
|
{
|
||||||
|
var min = new DateTimeOffset(date.Value.Year, date.Value.Month, date.Value.Day, 0, 0, 0, offset).ToUniversalTime();
|
||||||
|
var max = min.AddDays(1);
|
||||||
|
|
||||||
|
var createdQuery = query.Where(e => e.Creation >= min && e.Creation <= max);
|
||||||
|
var editedQuery = query.Where(e => e.Obsolete != null && e.Obsolete >= min && e.Obsolete <= max);
|
||||||
|
|
||||||
|
query = createdQuery.Union(editedQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
var entities = await query
|
||||||
|
.OrderBy(e => e.Creation)
|
||||||
|
.ThenBy(e => e.Obsolete)
|
||||||
|
.ThenBy(e => e.Id)
|
||||||
|
.ToListAsync(token);
|
||||||
|
var dtos = entities.Select(e => Convert(e, offset));
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<TDto>> Get(TRequest request, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = BuildQuery(request);
|
||||||
|
var entities = await query
|
||||||
|
.OrderBy(e => e.Creation)
|
||||||
|
.ThenBy(e => e.Obsolete)
|
||||||
|
.ThenBy(e => e.Id)
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
|
TimeSpan offset = GetTimezoneOffset(request);
|
||||||
|
var dtos = entities.Select(e => Convert(e, offset));
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract TimeSpan GetTimezoneOffset(TRequest request);
|
||||||
|
|
||||||
|
protected abstract IQueryable<TEntity> BuildQuery(TRequest request);
|
||||||
|
|
||||||
|
protected virtual TEntity Convert(TDto dto)
|
||||||
|
{
|
||||||
|
var entity = dto.Adapt<TEntity>();
|
||||||
|
entity.Creation = entity.Creation.ToUniversalTime();
|
||||||
|
|
||||||
|
if(entity.Obsolete.HasValue)
|
||||||
|
entity.Obsolete = entity.Obsolete.Value.ToUniversalTime();
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual TDto Convert(TEntity entity, TimeSpan offset)
|
||||||
|
{
|
||||||
|
var dto = entity.Adapt<TDto>();
|
||||||
|
dto.Creation = entity.Creation.ToOffset(offset);
|
||||||
|
|
||||||
|
if (entity.Obsolete.HasValue)
|
||||||
|
dto.Obsolete = entity.Obsolete.Value.ToOffset(offset);
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<int> SaveChangesWithExceptionHandling(CancellationToken token)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await context.SaveChangesAsync(token);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (DbUpdateException ex)
|
||||||
|
{
|
||||||
|
if (ex.InnerException is PostgresException pgException)
|
||||||
|
TryConvertPostgresExceptionToValidateException(pgException);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void TryConvertPostgresExceptionToValidateException(PostgresException pgException)
|
||||||
|
{
|
||||||
|
if (pgException.SqlState == PostgresErrorCodes.ForeignKeyViolation)
|
||||||
|
throw new ArgumentInvalidException("dtos", pgException.Message + "\r\n" + pgException.Detail);
|
||||||
|
}
|
||||||
|
}
|
@ -1,113 +1,34 @@
|
|||||||
using AsbCloudApp.Data.ProcessMapPlan;
|
using AsbCloudApp.Data.ProcessMapPlan;
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
using AsbCloudApp.Repositories;
|
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using AsbCloudDb.Model.ProcessMapPlan;
|
using AsbCloudDb.Model.ProcessMapPlan;
|
||||||
using AsbCloudDb.Model.WellSections;
|
|
||||||
using Mapster;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Npgsql;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Repository;
|
namespace AsbCloudInfrastructure.Repository;
|
||||||
|
|
||||||
public class ProcessMapPlanBaseRepository<TDto, TEntity> : IProcessMapPlanBaseRepository<TDto>
|
public class ProcessMapPlanBaseRepository<TDto, TEntity> : ChangeLogRepositoryAbstract<TDto, TEntity, ProcessMapPlanBaseRequestWithWell>
|
||||||
where TDto : ProcessMapPlanBaseDto
|
where TDto : ProcessMapPlanBaseDto
|
||||||
where TEntity : ProcessMapPlanBase
|
where TEntity : ProcessMapPlanBase
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext context;
|
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
|
|
||||||
public ProcessMapPlanBaseRepository(IAsbCloudDbContext context, IWellService wellService)
|
public ProcessMapPlanBaseRepository(IAsbCloudDbContext context, IWellService wellService)
|
||||||
|
: base(context)
|
||||||
{
|
{
|
||||||
this.context = context;
|
|
||||||
this.wellService = wellService;
|
this.wellService = wellService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> InsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
protected override IQueryable<TEntity> BuildQuery(ProcessMapPlanBaseRequestWithWell request)
|
||||||
{
|
{
|
||||||
var result = 0;
|
|
||||||
if (dtos.Any())
|
|
||||||
{
|
|
||||||
var entities = dtos.Select(Convert);
|
|
||||||
var creation = DateTimeOffset.UtcNow;
|
|
||||||
var dbSet = context.Set<TEntity>();
|
|
||||||
foreach (var entity in entities) {
|
|
||||||
entity.Id = default;
|
|
||||||
entity.IdAuthor = idUser;
|
|
||||||
entity.Creation = creation;
|
|
||||||
entity.IdState = ChangeLogAbstract.IdStateActual;
|
|
||||||
entity.IdEditor = null;
|
|
||||||
entity.Editor = null;
|
|
||||||
entity.IdPrevious = null;
|
|
||||||
entity.Obsolete = null;
|
|
||||||
dbSet.Add(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
result += await SaveChangesWithExceptionHandling(token);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> ClearAndInsertRange(int idUser, int idWell, IEnumerable<TDto> dtos, CancellationToken token)
|
|
||||||
{
|
|
||||||
if (dtos.Any(d => d.IdWell != idWell))
|
|
||||||
throw new ArgumentInvalidException(nameof(dtos), $"Все записи должны относиться к скважине idWell = {idWell}");
|
|
||||||
|
|
||||||
using var transaction = context.Database.BeginTransaction();
|
|
||||||
var result = 0;
|
|
||||||
|
|
||||||
var dbSet = context.Set<TEntity>();
|
|
||||||
var entitiesToMarkDeleted = dbSet
|
|
||||||
.Where(e => e.IdWell == idWell)
|
|
||||||
.Where(e => e.Obsolete == null);
|
|
||||||
var obsolete = DateTimeOffset.UtcNow;
|
|
||||||
foreach (var entity in entitiesToMarkDeleted)
|
|
||||||
{
|
|
||||||
entity.IdState = ChangeLogAbstract.IdClearedOnImport;
|
|
||||||
entity.Obsolete = obsolete;
|
|
||||||
entity.IdEditor = idUser;
|
|
||||||
}
|
|
||||||
result += await SaveChangesWithExceptionHandling(token);
|
|
||||||
result += await InsertRange(idUser, dtos, token);
|
|
||||||
await transaction.CommitAsync(token);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token)
|
|
||||||
{
|
|
||||||
var dbSet = context.Set<TEntity>();
|
|
||||||
var entitiesToMarkDeleted = dbSet
|
|
||||||
.Where(e => ids.Contains(e.Id))
|
|
||||||
.Where(e => e.Obsolete == null);
|
|
||||||
var obsolete = DateTimeOffset.UtcNow;
|
|
||||||
foreach (var entity in entitiesToMarkDeleted)
|
|
||||||
{
|
|
||||||
entity.IdState = ChangeLogAbstract.IdStateDeleted;
|
|
||||||
entity.Obsolete = obsolete;
|
|
||||||
entity.IdEditor = idUser;
|
|
||||||
}
|
|
||||||
var result = await SaveChangesWithExceptionHandling(token);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<TDto>> Get(int idWell, ProcessMapPlanBaseRequest request, CancellationToken token)
|
|
||||||
{
|
|
||||||
var timezone = wellService.GetTimezone(idWell);
|
|
||||||
var offset = TimeSpan.FromHours(timezone.Hours);
|
|
||||||
|
|
||||||
var query = context
|
var query = context
|
||||||
.Set<TEntity>()
|
.Set<TEntity>()
|
||||||
.Include(e => e.Author)
|
.Include(e => e.Author)
|
||||||
.Include(e => e.Editor)
|
.Include(e => e.Editor)
|
||||||
.Where(e => e.IdWell == idWell);
|
.Include(e => e.Well)
|
||||||
|
.Where(e => e.IdWell == request.IdWell);
|
||||||
|
|
||||||
if (request.IdWellSectionType.HasValue)
|
if (request.IdWellSectionType.HasValue)
|
||||||
query = query.Where(e => e.IdWellSectionType == request.IdWellSectionType);
|
query = query.Where(e => e.IdWellSectionType == request.IdWellSectionType);
|
||||||
@ -126,156 +47,13 @@ public class ProcessMapPlanBaseRepository<TDto, TEntity> : IProcessMapPlanBaseRe
|
|||||||
.Where(e => e.Obsolete == null || e.Obsolete >= moment);
|
.Where(e => e.Obsolete == null || e.Obsolete >= moment);
|
||||||
}
|
}
|
||||||
|
|
||||||
var entities = await query.ToArrayAsync(token);
|
return query;
|
||||||
var dtos = entities.Select(e => Convert(e, offset));
|
|
||||||
return dtos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TDto>> GetChangeLog(int idWell, DateOnly? date, CancellationToken token)
|
protected override TimeSpan GetTimezoneOffset(ProcessMapPlanBaseRequestWithWell request)
|
||||||
{
|
{
|
||||||
var query = context
|
var timezone = wellService.GetTimezone(request.IdWell);
|
||||||
.Set<TEntity>()
|
|
||||||
.Include(e => e.Author)
|
|
||||||
.Include(e => e.Editor)
|
|
||||||
.Where(e => e.IdWell == idWell);
|
|
||||||
|
|
||||||
var timezone = wellService.GetTimezone(idWell);
|
|
||||||
var offset = TimeSpan.FromHours(timezone.Hours);
|
var offset = TimeSpan.FromHours(timezone.Hours);
|
||||||
|
return offset;
|
||||||
if (date.HasValue)
|
|
||||||
{
|
|
||||||
var min = new DateTimeOffset(date.Value.Year, date.Value.Month, date.Value.Day, 0, 0, 0, offset).ToUniversalTime();
|
|
||||||
var max = min.AddDays(1);
|
|
||||||
|
|
||||||
var createdQuery = query.Where(e => e.Creation >= min && e.Creation <= max);
|
|
||||||
var editedQuery = query.Where(e => e.Obsolete != null && e.Obsolete >= min && e.Obsolete <= max);
|
|
||||||
|
|
||||||
query = createdQuery.Union(editedQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
var entities = await query.ToListAsync(token);
|
|
||||||
var dtos = entities.Select(e => Convert(e, offset));
|
|
||||||
|
|
||||||
return dtos;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<DateOnly>> GetDatesChange(int idWell, CancellationToken token)
|
|
||||||
{
|
|
||||||
var wellEntitiesQuery = context
|
|
||||||
.Set<TEntity>()
|
|
||||||
.Where(e => e.IdWell == idWell);
|
|
||||||
|
|
||||||
var datesCreateQuery = wellEntitiesQuery
|
|
||||||
.Select(e => e.Creation)
|
|
||||||
.Distinct();
|
|
||||||
|
|
||||||
var datesCreate = await datesCreateQuery.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var datesUpdateQuery = wellEntitiesQuery
|
|
||||||
.Where(e => e.Obsolete != null)
|
|
||||||
.Select(e => e.Obsolete!.Value)
|
|
||||||
.Distinct();
|
|
||||||
|
|
||||||
var datesUpdate = await datesUpdateQuery.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var timezone = wellService.GetTimezone(idWell);
|
|
||||||
var offset = TimeSpan.FromHours(timezone.Hours);
|
|
||||||
|
|
||||||
var dates = Enumerable.Concat( datesCreate, datesUpdate);
|
|
||||||
dates = dates.Select(date => date.ToOffset(offset));
|
|
||||||
var datesOnly = dates
|
|
||||||
.Select(d => new DateOnly(d.Year, d.Month, d.Day))
|
|
||||||
.Distinct();
|
|
||||||
|
|
||||||
return datesOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> UpdateRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
|
||||||
{
|
|
||||||
if (dtos.Any(d => d.Id == 0))
|
|
||||||
throw new ArgumentInvalidException(nameof(dtos), "Отредактированные значения должны иметь id больше 0");
|
|
||||||
|
|
||||||
if (!dtos.Any())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
using var transaction = context.Database.BeginTransaction();
|
|
||||||
var result = 0;
|
|
||||||
|
|
||||||
var ids = dtos.Select(d => d.Id);
|
|
||||||
var dbSet = context.Set<TEntity>();
|
|
||||||
|
|
||||||
var entitiesToDelete = dbSet
|
|
||||||
.Where(e => ids.Contains(e.Id));
|
|
||||||
|
|
||||||
var updateTime = DateTimeOffset.UtcNow;
|
|
||||||
foreach (var entity in entitiesToDelete)
|
|
||||||
{
|
|
||||||
if(entity.Obsolete is not null)
|
|
||||||
throw new ArgumentInvalidException(nameof(dtos), "Недопустимо редактировать устаревшие записи");
|
|
||||||
entity.IdState = ChangeLogAbstract.IdStateReplaced;
|
|
||||||
entity.Obsolete = updateTime;
|
|
||||||
entity.IdEditor = idUser;
|
|
||||||
}
|
|
||||||
result += await context.SaveChangesAsync(token);
|
|
||||||
|
|
||||||
var entitiesNew = dtos.Select(Convert);
|
|
||||||
foreach (var entity in entitiesNew)
|
|
||||||
{
|
|
||||||
entity.IdPrevious = entity.Id;
|
|
||||||
entity.Id = default;
|
|
||||||
entity.Creation = updateTime;
|
|
||||||
entity.IdAuthor = idUser;
|
|
||||||
entity.Obsolete = null;
|
|
||||||
entity.IdEditor = null;
|
|
||||||
entity.IdState = ChangeLogAbstract.IdStateActual;
|
|
||||||
dbSet.Add(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
result += await SaveChangesWithExceptionHandling(token);
|
|
||||||
await transaction.CommitAsync(token);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual TEntity Convert(TDto dto)
|
|
||||||
{
|
|
||||||
var entity = dto.Adapt<TEntity>();
|
|
||||||
entity.Creation = entity.Creation.ToUniversalTime();
|
|
||||||
|
|
||||||
if(entity.Obsolete.HasValue)
|
|
||||||
entity.Obsolete = entity.Obsolete.Value.ToUniversalTime();
|
|
||||||
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual TDto Convert(TEntity entity, TimeSpan offset)
|
|
||||||
{
|
|
||||||
var dto = entity.Adapt<TDto>();
|
|
||||||
dto.Creation = entity.Creation.ToOffset(offset);
|
|
||||||
|
|
||||||
if (entity.Obsolete.HasValue)
|
|
||||||
dto.Obsolete = entity.Obsolete.Value.ToOffset(offset);
|
|
||||||
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<int> SaveChangesWithExceptionHandling(CancellationToken token)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var result = await context.SaveChangesAsync(token);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch (DbUpdateException ex)
|
|
||||||
{
|
|
||||||
if (ex.InnerException is PostgresException pgException)
|
|
||||||
TryConvertPostgresExceptionToValidateException(pgException);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void TryConvertPostgresExceptionToValidateException(PostgresException pgException)
|
|
||||||
{
|
|
||||||
if (pgException.SqlState == PostgresErrorCodes.ForeignKeyViolation)
|
|
||||||
throw new ArgumentInvalidException("dtos", pgException.Message + "\r\n" + pgException.Detail);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,12 +383,12 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
new[] { nameof(wellOperationDtos) });
|
new[] { nameof(wellOperationDtos) });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousDateEnd > currentDateStart)
|
//if (previousDateEnd > currentDateStart)
|
||||||
{
|
//{
|
||||||
yield return new ValidationResult(
|
// yield return new ValidationResult(
|
||||||
"Предыдущая операция не завершена",
|
// "Предыдущая операция не завершена",
|
||||||
new[] { nameof(wellOperationDtos) });
|
// new[] { nameof(wellOperationDtos) });
|
||||||
}
|
//}
|
||||||
|
|
||||||
previous = current;
|
previous = current;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ public interface IProcessMapPlanDrillingClient
|
|||||||
[Delete(BaseRoute)]
|
[Delete(BaseRoute)]
|
||||||
Task<IApiResponse<int>> DeleteRange(int idWell, [Body] IEnumerable<int> ids);
|
Task<IApiResponse<int>> DeleteRange(int idWell, [Body] IEnumerable<int> ids);
|
||||||
|
|
||||||
|
[Delete($"{BaseRoute}/clear")]
|
||||||
|
Task<IApiResponse<int>> Clear(int idWell);
|
||||||
|
|
||||||
[Get(BaseRoute)]
|
[Get(BaseRoute)]
|
||||||
Task<IApiResponse<IEnumerable<ProcessMapPlanDrillingDto>>> Get(int idWell, ProcessMapPlanBaseRequest request);
|
Task<IApiResponse<IEnumerable<ProcessMapPlanDrillingDto>>> Get(int idWell, ProcessMapPlanBaseRequest request);
|
||||||
|
|
||||||
@ -28,5 +31,5 @@ public interface IProcessMapPlanDrillingClient
|
|||||||
Task<IApiResponse<IEnumerable<DateOnly>>> GetDatesChange(int idWell);
|
Task<IApiResponse<IEnumerable<DateOnly>>> GetDatesChange(int idWell);
|
||||||
|
|
||||||
[Put(BaseRoute)]
|
[Put(BaseRoute)]
|
||||||
Task<IApiResponse<int>> UpdateRangeAsync(int idWell, IEnumerable<ProcessMapPlanDrillingDto> dtos);
|
Task<IApiResponse<int>> UpdateOrInsertRange(int idWell, IEnumerable<ProcessMapPlanDrillingDto> dtos);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
|
|||||||
Assert.Equal(2, count);
|
Assert.Equal(2, count);
|
||||||
|
|
||||||
var oldEntity = dbset.First(p => p.Id == entry.Entity.Id);
|
var oldEntity = dbset.First(p => p.Id == entry.Entity.Id);
|
||||||
Assert.Equal(ProcessMapPlanBase.IdClearedOnImport, oldEntity.IdState);
|
Assert.Equal(ProcessMapPlanBase.IdCleared, oldEntity.IdState);
|
||||||
Assert.Equal(1, oldEntity.IdEditor);
|
Assert.Equal(1, oldEntity.IdEditor);
|
||||||
Assert.NotNull(oldEntity.Obsolete);
|
Assert.NotNull(oldEntity.Obsolete);
|
||||||
Assert.InRange(oldEntity.Obsolete.Value, startTime, doneTime);
|
Assert.InRange(oldEntity.Obsolete.Value, startTime, doneTime);
|
||||||
@ -194,7 +194,7 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task UpdateRange_returns_success()
|
public async Task UpdateOrInsertRange_returns_success()
|
||||||
{
|
{
|
||||||
// arrange
|
// arrange
|
||||||
var startTime = DateTimeOffset.UtcNow;
|
var startTime = DateTimeOffset.UtcNow;
|
||||||
@ -205,33 +205,50 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
|
|||||||
dbContext.SaveChanges();
|
dbContext.SaveChanges();
|
||||||
entry.State = EntityState.Detached;
|
entry.State = EntityState.Detached;
|
||||||
|
|
||||||
var dtoCopy = dto.Adapt<ProcessMapPlanDrillingDto>();
|
var dtoUpdate = dto.Adapt<ProcessMapPlanDrillingDto>();
|
||||||
dtoCopy.Id = entry.Entity.Id;
|
dtoUpdate.Id = entry.Entity.Id;
|
||||||
dtoCopy.Comment = "nebuchadnezzar";
|
dtoUpdate.Comment = "nebuchadnezzar";
|
||||||
dtoCopy.DeltaPressureLimitMax ++;
|
dtoUpdate.DeltaPressureLimitMax++;
|
||||||
dtoCopy.DeltaPressurePlan ++;
|
dtoUpdate.DeltaPressurePlan++;
|
||||||
dtoCopy.FlowPlan ++;
|
dtoUpdate.FlowPlan++;
|
||||||
dtoCopy.FlowLimitMax ++;
|
dtoUpdate.FlowLimitMax++;
|
||||||
dtoCopy.RopPlan ++;
|
dtoUpdate.RopPlan++;
|
||||||
dtoCopy.AxialLoadPlan ++;
|
dtoUpdate.AxialLoadPlan++;
|
||||||
dtoCopy.AxialLoadLimitMax ++;
|
dtoUpdate.AxialLoadLimitMax++;
|
||||||
dtoCopy.DepthStart ++;
|
dtoUpdate.DepthStart++;
|
||||||
dtoCopy.DepthEnd ++;
|
dtoUpdate.DepthEnd++;
|
||||||
dtoCopy.TopDriveSpeedPlan ++;
|
dtoUpdate.TopDriveSpeedPlan++;
|
||||||
dtoCopy.TopDriveSpeedLimitMax ++;
|
dtoUpdate.TopDriveSpeedLimitMax++;
|
||||||
dtoCopy.TopDriveTorquePlan ++;
|
dtoUpdate.TopDriveTorquePlan++;
|
||||||
dtoCopy.TopDriveTorqueLimitMax ++;
|
dtoUpdate.TopDriveTorqueLimitMax++;
|
||||||
|
|
||||||
|
var dtoInsert = dtoUpdate.Adapt<ProcessMapPlanDrillingDto>();
|
||||||
|
dtoInsert.Id = 0;
|
||||||
|
dtoInsert.Comment = "nebuchad";
|
||||||
|
dtoInsert.DeltaPressureLimitMax++;
|
||||||
|
dtoInsert.DeltaPressurePlan++;
|
||||||
|
dtoInsert.FlowPlan++;
|
||||||
|
dtoInsert.FlowLimitMax++;
|
||||||
|
dtoInsert.RopPlan++;
|
||||||
|
dtoInsert.AxialLoadPlan++;
|
||||||
|
dtoInsert.AxialLoadLimitMax++;
|
||||||
|
dtoInsert.DepthStart++;
|
||||||
|
dtoInsert.DepthEnd++;
|
||||||
|
dtoInsert.TopDriveSpeedPlan++;
|
||||||
|
dtoInsert.TopDriveSpeedLimitMax++;
|
||||||
|
dtoInsert.TopDriveTorquePlan++;
|
||||||
|
dtoInsert.TopDriveTorqueLimitMax++;
|
||||||
|
|
||||||
// act
|
// act
|
||||||
var result = await client.UpdateRangeAsync(entity.IdWell, new ProcessMapPlanDrillingDto[] { dtoCopy });
|
var result = await client.UpdateOrInsertRange(entity.IdWell, new ProcessMapPlanDrillingDto[] { dtoUpdate, dtoInsert });
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
var doneTime = DateTimeOffset.UtcNow;
|
var doneTime = DateTimeOffset.UtcNow;
|
||||||
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
|
||||||
Assert.Equal(2, result.Content);
|
Assert.Equal(3, result.Content);
|
||||||
|
|
||||||
var count = dbset.Count();
|
var count = dbset.Count();
|
||||||
Assert.Equal(2, count);
|
Assert.Equal(3, count);
|
||||||
|
|
||||||
var oldEntity = dbset.First(p => p.Id == entry.Entity.Id);
|
var oldEntity = dbset.First(p => p.Id == entry.Entity.Id);
|
||||||
Assert.Equal(ProcessMapPlanBase.IdStateReplaced, oldEntity.IdState);
|
Assert.Equal(ProcessMapPlanBase.IdStateReplaced, oldEntity.IdState);
|
||||||
@ -239,7 +256,7 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
|
|||||||
Assert.NotNull(oldEntity.Obsolete);
|
Assert.NotNull(oldEntity.Obsolete);
|
||||||
Assert.InRange(oldEntity.Obsolete.Value, startTime, doneTime);
|
Assert.InRange(oldEntity.Obsolete.Value, startTime, doneTime);
|
||||||
|
|
||||||
var newEntity = dbset.First(p => p.Id != entry.Entity.Id);
|
var newEntity = dbset.First(p => p.Comment == dtoUpdate.Comment);
|
||||||
Assert.Equal(ProcessMapPlanBase.IdStateActual, newEntity.IdState);
|
Assert.Equal(ProcessMapPlanBase.IdStateActual, newEntity.IdState);
|
||||||
Assert.Equal(1, newEntity.IdAuthor);
|
Assert.Equal(1, newEntity.IdAuthor);
|
||||||
Assert.Null(newEntity.IdEditor);
|
Assert.Null(newEntity.IdEditor);
|
||||||
@ -247,7 +264,7 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
|
|||||||
Assert.Equal(oldEntity.Id, newEntity.IdPrevious);
|
Assert.Equal(oldEntity.Id, newEntity.IdPrevious);
|
||||||
Assert.InRange(newEntity.Creation, startTime, doneTime);
|
Assert.InRange(newEntity.Creation, startTime, doneTime);
|
||||||
|
|
||||||
var expected = dtoCopy.Adapt<ProcessMapPlanDrilling>();
|
var expected = dtoUpdate.Adapt<ProcessMapPlanDrilling>();
|
||||||
var excludeProps = new[] {
|
var excludeProps = new[] {
|
||||||
nameof(ProcessMapPlanDrilling.Id),
|
nameof(ProcessMapPlanDrilling.Id),
|
||||||
nameof(ProcessMapPlanDrilling.Author),
|
nameof(ProcessMapPlanDrilling.Author),
|
||||||
@ -289,6 +306,39 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
|
|||||||
Assert.InRange(actual.Obsolete.Value, startTime, doneTime);
|
Assert.InRange(actual.Obsolete.Value, startTime, doneTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Clear_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var dbset = dbContext.Set<ProcessMapPlanDrilling>();
|
||||||
|
|
||||||
|
var entry = dbset.Add(entity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
entry.State = EntityState.Detached;
|
||||||
|
|
||||||
|
var startTime = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await client.Clear(dto.IdWell);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
var doneTime = DateTimeOffset.UtcNow;
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.Equal(1, response.Content);
|
||||||
|
|
||||||
|
var actual = dbContext
|
||||||
|
.Set<ProcessMapPlanDrilling>()
|
||||||
|
.FirstOrDefault(p => p.Id == entry.Entity.Id);
|
||||||
|
|
||||||
|
Assert.NotNull(actual);
|
||||||
|
Assert.Equal(ProcessMapPlanBase.IdCleared, actual.IdState);
|
||||||
|
Assert.Equal(1, actual.IdEditor);
|
||||||
|
Assert.NotNull(actual.Obsolete);
|
||||||
|
Assert.InRange(actual.Obsolete.Value, startTime, doneTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetDatesChange_returns_success()
|
public async Task GetDatesChange_returns_success()
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@ using AsbCloudApp.Data;
|
|||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using AsbCloudWebApi.IntegrationTests.Clients;
|
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace AsbCloudWebApi.IntegrationTests.Controllers;
|
namespace AsbCloudWebApi.IntegrationTests.Controllers;
|
||||||
@ -10,7 +11,7 @@ public class SlipsStatControllerTest : BaseIntegrationTest
|
|||||||
{
|
{
|
||||||
private static readonly Schedule schedule = new()
|
private static readonly Schedule schedule = new()
|
||||||
{
|
{
|
||||||
Id = 1,
|
Id = 0,
|
||||||
IdDriller = Data.Defaults.Drillers[0].Id,
|
IdDriller = Data.Defaults.Drillers[0].Id,
|
||||||
IdWell = Data.Defaults.Wells[0].Id,
|
IdWell = Data.Defaults.Wells[0].Id,
|
||||||
ShiftStart = new TimeOnly(8, 0, 0),
|
ShiftStart = new TimeOnly(8, 0, 0),
|
||||||
@ -21,7 +22,7 @@ public class SlipsStatControllerTest : BaseIntegrationTest
|
|||||||
|
|
||||||
private static readonly DetectedOperation detectedOperation = new()
|
private static readonly DetectedOperation detectedOperation = new()
|
||||||
{
|
{
|
||||||
Id = 1,
|
Id = 0,
|
||||||
IdTelemetry = Data.Defaults.Telemetries[0].Id,
|
IdTelemetry = Data.Defaults.Telemetries[0].Id,
|
||||||
IdCategory = WellOperationCategory.IdSlipsTime,
|
IdCategory = WellOperationCategory.IdSlipsTime,
|
||||||
DateStart = new DateTimeOffset(new DateTime(2024, 1, 23, 15, 0, 0, 0, DateTimeKind.Utc)),
|
DateStart = new DateTimeOffset(new DateTime(2024, 1, 23, 15, 0, 0, 0, DateTimeKind.Utc)),
|
||||||
@ -34,7 +35,7 @@ public class SlipsStatControllerTest : BaseIntegrationTest
|
|||||||
|
|
||||||
private static readonly WellOperation factWellOperation = new()
|
private static readonly WellOperation factWellOperation = new()
|
||||||
{
|
{
|
||||||
Id = 1,
|
Id = 0,
|
||||||
IdWell = Data.Defaults.Wells[0].Id,
|
IdWell = Data.Defaults.Wells[0].Id,
|
||||||
IdWellSectionType = 1,
|
IdWellSectionType = 1,
|
||||||
IdCategory = WellOperationCategory.IdRotor,
|
IdCategory = WellOperationCategory.IdRotor,
|
||||||
@ -51,9 +52,18 @@ public class SlipsStatControllerTest : BaseIntegrationTest
|
|||||||
public SlipsStatControllerTest(WebAppFactoryFixture factory)
|
public SlipsStatControllerTest(WebAppFactoryFixture factory)
|
||||||
: base(factory)
|
: base(factory)
|
||||||
{
|
{
|
||||||
dbContext.Schedule.Add(schedule);
|
var schedules = dbContext.Set<Schedule>();
|
||||||
dbContext.DetectedOperations.Add(detectedOperation);
|
var detectedOperations = dbContext.Set<DetectedOperation>();
|
||||||
dbContext.WellOperations.Add(factWellOperation);
|
var wellOperations = dbContext.Set<WellOperation>();
|
||||||
|
|
||||||
|
schedules.RemoveRange(schedules);
|
||||||
|
detectedOperations.RemoveRange(detectedOperations);
|
||||||
|
wellOperations.RemoveRange(wellOperations);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
|
||||||
|
schedules.Add(schedule);
|
||||||
|
detectedOperations.Add(detectedOperation);
|
||||||
|
wellOperations.Add(factWellOperation);
|
||||||
dbContext.SaveChanges();
|
dbContext.SaveChanges();
|
||||||
|
|
||||||
client = factory.GetAuthorizedHttpClient<ISlipsTimeClient>();
|
client = factory.GetAuthorizedHttpClient<ISlipsTimeClient>();
|
||||||
|
@ -23,10 +23,10 @@ namespace AsbCloudWebApi.Controllers.ProcessMapPlan;
|
|||||||
public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
||||||
where TDto : ProcessMapPlanBaseDto
|
where TDto : ProcessMapPlanBaseDto
|
||||||
{
|
{
|
||||||
private readonly IProcessMapPlanBaseRepository<TDto> repository;
|
private readonly IChangeLogRepository<TDto, ProcessMapPlanBaseRequestWithWell> repository;
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
|
|
||||||
public ProcessMapPlanBaseController(IProcessMapPlanBaseRepository<TDto> repository, IWellService wellService)
|
public ProcessMapPlanBaseController(IChangeLogRepository<TDto, ProcessMapPlanBaseRequestWithWell> repository, IWellService wellService)
|
||||||
{
|
{
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.wellService = wellService;
|
this.wellService = wellService;
|
||||||
@ -68,7 +68,9 @@ public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
|||||||
return this.ValidationBadRequest(nameof(dtos), "all dtos should contain same idWell");
|
return this.ValidationBadRequest(nameof(dtos), "all dtos should contain same idWell");
|
||||||
|
|
||||||
var idUser = await AssertUserHasAccessToWell(idWell, token);
|
var idUser = await AssertUserHasAccessToWell(idWell, token);
|
||||||
var result = await repository.ClearAndInsertRange(idUser, idWell, dtos, token);
|
|
||||||
|
var request = new ProcessMapPlanBaseRequestWithWell(idWell);
|
||||||
|
var result = await repository.ClearAndInsertRange(idUser, request, dtos, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,10 +87,29 @@ public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
|||||||
public async Task<IActionResult> DeleteRange([FromRoute]int idWell, IEnumerable<int> ids, CancellationToken token)
|
public async Task<IActionResult> DeleteRange([FromRoute]int idWell, IEnumerable<int> ids, CancellationToken token)
|
||||||
{
|
{
|
||||||
var idUser = await AssertUserHasAccessToWell(idWell, token);
|
var idUser = await AssertUserHasAccessToWell(idWell, token);
|
||||||
|
|
||||||
var result = await repository.DeleteRange(idUser, ids, token);
|
var result = await repository.DeleteRange(idUser, ids, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Очистка
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete("clear")]
|
||||||
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<IActionResult> Clear([FromRoute] int idWell, CancellationToken token)
|
||||||
|
{
|
||||||
|
var idUser = await AssertUserHasAccessToWell(idWell, token);
|
||||||
|
|
||||||
|
var request = new ProcessMapPlanBaseRequestWithWell(idWell);
|
||||||
|
var result = await repository.Clear(idUser, request, token);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение
|
/// Получение
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -102,7 +123,9 @@ public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
|||||||
public async Task<ActionResult<IEnumerable<TDto>>> Get([FromRoute] int idWell, [FromQuery]ProcessMapPlanBaseRequest request, CancellationToken token)
|
public async Task<ActionResult<IEnumerable<TDto>>> Get([FromRoute] int idWell, [FromQuery]ProcessMapPlanBaseRequest request, CancellationToken token)
|
||||||
{
|
{
|
||||||
await AssertUserHasAccessToWell(idWell, token);
|
await AssertUserHasAccessToWell(idWell, token);
|
||||||
var result = await repository.Get(idWell, request, token);
|
|
||||||
|
var serviceRequest = new ProcessMapPlanBaseRequestWithWell(request, idWell);
|
||||||
|
var result = await repository.Get(serviceRequest, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +142,9 @@ public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
|||||||
public async Task<ActionResult<IEnumerable<TDto>>> GetChangeLog([FromRoute] int idWell, [FromQuery] DateOnly? date, CancellationToken token)
|
public async Task<ActionResult<IEnumerable<TDto>>> GetChangeLog([FromRoute] int idWell, [FromQuery] DateOnly? date, CancellationToken token)
|
||||||
{
|
{
|
||||||
await AssertUserHasAccessToWell(idWell, token);
|
await AssertUserHasAccessToWell(idWell, token);
|
||||||
var result = await repository.GetChangeLog(idWell, date, token);
|
|
||||||
|
var serviceRequest = new ProcessMapPlanBaseRequestWithWell(idWell);
|
||||||
|
var result = await repository.GetChangeLog(serviceRequest, date, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,21 +160,23 @@ public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
|||||||
public async Task<ActionResult<IEnumerable<DateOnly>>> GetDatesChange([FromRoute] int idWell, CancellationToken token)
|
public async Task<ActionResult<IEnumerable<DateOnly>>> GetDatesChange([FromRoute] int idWell, CancellationToken token)
|
||||||
{
|
{
|
||||||
await AssertUserHasAccessToWell(idWell, token);
|
await AssertUserHasAccessToWell(idWell, token);
|
||||||
var result = await repository.GetDatesChange(idWell, token);
|
|
||||||
|
var serviceRequest = new ProcessMapPlanBaseRequestWithWell(idWell);
|
||||||
|
var result = await repository.GetDatesChange(serviceRequest, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Редактирование
|
/// Редактирование или добавление [для пакетного редактирования]
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idWell"></param>
|
/// <param name="idWell"></param>
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPut]
|
[HttpPut()]
|
||||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
public async Task<IActionResult> UpdateRange([FromRoute] int idWell, IEnumerable<TDto> dtos, CancellationToken token)
|
public async Task<IActionResult> UpdateOrInsertRange([FromRoute] int idWell, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
{
|
{
|
||||||
var first = dtos.FirstOrDefault();
|
var first = dtos.FirstOrDefault();
|
||||||
if (first is null)
|
if (first is null)
|
||||||
@ -160,7 +187,7 @@ public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
|||||||
|
|
||||||
var idUser = await AssertUserHasAccessToWell(idWell, token);
|
var idUser = await AssertUserHasAccessToWell(idWell, token);
|
||||||
|
|
||||||
var result = await repository.UpdateRange(idUser, dtos, token);
|
var result = await repository.UpdateOrInsertRange(idUser, dtos, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
using AsbCloudApp.Data.ProcessMapPlan;
|
using AsbCloudApp.Data.ProcessMapPlan;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Controllers.ProcessMapPlan;
|
namespace AsbCloudWebApi.Controllers.ProcessMapPlan;
|
||||||
|
|
||||||
public class ProcessMapPlanDrillingController : ProcessMapPlanBaseController<ProcessMapPlanDrillingDto>
|
public class ProcessMapPlanDrillingController : ProcessMapPlanBaseController<ProcessMapPlanDrillingDto>
|
||||||
{
|
{
|
||||||
public ProcessMapPlanDrillingController(IProcessMapPlanBaseRepository<ProcessMapPlanDrillingDto> repository, IWellService wellService)
|
public ProcessMapPlanDrillingController(
|
||||||
|
IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> repository,
|
||||||
|
IWellService wellService)
|
||||||
: base(repository, wellService)
|
: base(repository, wellService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,9 @@ namespace Microsoft.AspNetCore.Mvc
|
|||||||
{
|
{
|
||||||
var errors = validationResults
|
var errors = validationResults
|
||||||
.SelectMany(e => e.MemberNames.Select(name => new { name, e.ErrorMessage }))
|
.SelectMany(e => e.MemberNames.Select(name => new { name, e.ErrorMessage }))
|
||||||
.ToDictionary(e => e.name, e => new[] { e.ErrorMessage ?? string.Empty });
|
.GroupBy(e => e.name)
|
||||||
|
.ToDictionary(e => e.Key, e => e.Select(el => el.ErrorMessage ?? string.Empty).ToArray());
|
||||||
|
|
||||||
var problem = new ValidationProblemDetails(errors);
|
var problem = new ValidationProblemDetails(errors);
|
||||||
return controller.BadRequest(problem);
|
return controller.BadRequest(problem);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user