Фикс бага с временными диапазонами

1. Фикс репозитория + небольшой рефакторинг
2. Фикс сервиса импорта
3. Фикс тестов
This commit is contained in:
Степанов Дмитрий 2024-02-07 07:21:03 +03:00
parent 04156863a1
commit 8bfb7806a3
5 changed files with 63 additions and 46 deletions

View File

@ -75,16 +75,15 @@ public class WellOperationRepository : IWellOperationRepository
OperationType = WellOperation.IdOperationTypePlan, OperationType = WellOperation.IdOperationTypePlan,
}; };
var entities = await BuildQuery(request) var dtos = await BuildQuery(request)
.AsNoTracking() .AsNoTracking()
.ToArrayAsync(token) .ToArrayAsync(token);
.ConfigureAwait(false);
var dateLastAssosiatedPlanOperation = await GetDateLastAssosiatedPlanOperationAsync(idWell, currentDate, timezone.Hours, token); var dateLastAssosiatedPlanOperation = await GetDateLastAssosiatedPlanOperationAsync(idWell, currentDate, timezone.Hours, token);
var result = new WellOperationPlanDto() var result = new WellOperationPlanDto()
{ {
WellOperationsPlan = entities, WellOperationsPlan = dtos.Select(Convert),
DateLastAssosiatedPlanOperation = dateLastAssosiatedPlanOperation DateLastAssosiatedPlanOperation = dateLastAssosiatedPlanOperation
}; };
@ -226,7 +225,7 @@ public class WellOperationRepository : IWellOperationRepository
var dtos = await query.ToArrayAsync(token); var dtos = await query.ToArrayAsync(token);
return dtos; return dtos.Select(Convert);
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -234,21 +233,19 @@ public class WellOperationRepository : IWellOperationRepository
WellOperationRequest request, WellOperationRequest request,
CancellationToken token) CancellationToken token)
{ {
var query = BuildQuery(request) var query = BuildQuery(request);
.AsNoTracking();
var result = new PaginationContainer<WellOperationDto> var result = new PaginationContainer<WellOperationDto>
{ {
Skip = request.Skip ?? 0, Skip = request.Skip ?? 0,
Take = request.Take ?? 32, Take = request.Take ?? 32,
Count = await query.CountAsync(token).ConfigureAwait(false), Count = await query.CountAsync(token),
}; };
query = query var dtos = await query.ToArrayAsync(token);
.Skip(result.Skip)
.Take(result.Take); result.Items = dtos.Select(Convert);
result.Items = await query.ToArrayAsync(token);
return result; return result;
} }
@ -350,11 +347,13 @@ public class WellOperationRepository : IWellOperationRepository
OperationType = firstOperation.IdType, OperationType = firstOperation.IdType,
}; };
var entities = await BuildQuery(request) var dtos = await BuildQuery(request)
.AsNoTracking() .AsNoTracking()
.ToArrayAsync(token); .ToArrayAsync(token);
var wellOperationsUnion = entities.Union(wellOperationDtos).OrderBy(o => o.DateStart); var dtosWithRemoteDateTime = dtos.Select(Convert);
var wellOperationsUnion = dtosWithRemoteDateTime.Union(dtos).OrderBy(o => o.DateStart);
var results = Validate(wellOperationsUnion); var results = Validate(wellOperationsUnion);
return results; return results;
@ -368,16 +367,17 @@ public class WellOperationRepository : IWellOperationRepository
if (!enumerator.MoveNext()) if (!enumerator.MoveNext())
yield break; yield break;
var timezone = wellService.GetTimezone(wellOperationDtos.First().IdWell);
var timezoneOffset = timezone.Hours;
var previous = enumerator.Current; var previous = enumerator.Current;
while(enumerator.MoveNext()) while(enumerator.MoveNext())
{ {
var current = enumerator.Current; var current = enumerator.Current;
var previousDateStart = previous.DateStart.ToUniversalTime(); var previousDateStart = previous.DateStart.DateTime.ToUtcDateTimeOffset(timezoneOffset);
var currentDateStart = current.DateStart.ToUniversalTime(); var currentDateStart = current.DateStart.DateTime.ToUtcDateTimeOffset(timezoneOffset);
var previousDateEnd = previous.DateStart.AddHours(previous.DurationHours).ToUniversalTime();
if (previousDateStart.AddDays(Gap) < currentDateStart) if (previousDateStart.AddDays(Gap) < currentDateStart)
{ {
yield return new ValidationResult( yield return new ValidationResult(
@ -452,12 +452,13 @@ public class WellOperationRepository : IWellOperationRepository
/// В результате попрежнему требуется конвертировать дату /// В результате попрежнему требуется конвертировать дату
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
private IQueryable<WellOperationDto> BuildQuery(WellOperationRequest request) private IQueryable<WellOperationDto> BuildQuery(WellOperationRequest request)
{ {
var timezone = wellService.GetTimezone(request.IdWell); var timezone = wellService.GetTimezone(request.IdWell);
var timeZoneOffset = TimeSpan.FromHours(timezone.Hours); var timeZoneOffset = timezone.Hours;
var query = db.WellOperations var query = db.WellOperations
.Include(s => s.WellSectionType) .Include(s => s.WellSectionType)
.Include(s => s.OperationCategory) .Include(s => s.OperationCategory)
@ -481,20 +482,20 @@ public class WellOperationRepository : IWellOperationRepository
if (request.GeDate.HasValue) if (request.GeDate.HasValue)
{ {
var geDateOffset = request.GeDate.Value.ToUtcDateTimeOffset(timezone.Hours); var geDateOffset = request.GeDate.Value.ToUtcDateTimeOffset(timeZoneOffset);
query = query.Where(e => e.DateStart >= geDateOffset); query = query.Where(e => e.DateStart >= geDateOffset);
} }
if (request.LtDate.HasValue) if (request.LtDate.HasValue)
{ {
var ltDateOffset = request.LtDate.Value.ToUtcDateTimeOffset(timezone.Hours); var ltDateOffset = request.LtDate.Value.ToUtcDateTimeOffset(timeZoneOffset);
query = query.Where(e => e.DateStart < ltDateOffset); query = query.Where(e => e.DateStart < ltDateOffset);
} }
var currentWellOperations = db.WellOperations var currentWellOperations = db.WellOperations
.Where(subOp => subOp.IdWell == request.IdWell); .Where(subOp => subOp.IdWell == request.IdWell);
var wellOperationsWithCategoryNPT = currentWellOperations var wellOperationsWithCategoryNpt = currentWellOperations
.Where(subOp => subOp.IdType == 1) .Where(subOp => subOp.IdType == 1)
.Where(subOp => WellOperationCategory.NonProductiveTimeSubIds.Contains(subOp.IdCategory)); .Where(subOp => WellOperationCategory.NonProductiveTimeSubIds.Contains(subOp.IdCategory));
@ -510,14 +511,14 @@ public class WellOperationRepository : IWellOperationRepository
CategoryName = o.OperationCategory.Name, CategoryName = o.OperationCategory.Name,
WellSectionTypeName = o.WellSectionType.Caption, WellSectionTypeName = o.WellSectionType.Caption,
DateStart = DateTime.SpecifyKind(o.DateStart.UtcDateTime + timeZoneOffset, DateTimeKind.Unspecified), DateStart = o.DateStart,
DepthStart = o.DepthStart, DepthStart = o.DepthStart,
DepthEnd = o.DepthEnd, DepthEnd = o.DepthEnd,
DurationHours = o.DurationHours, DurationHours = o.DurationHours,
CategoryInfo = o.CategoryInfo, CategoryInfo = o.CategoryInfo,
Comment = o.Comment, Comment = o.Comment,
NptHours = wellOperationsWithCategoryNPT NptHours = wellOperationsWithCategoryNpt
.Where(subOp => subOp.DateStart <= o.DateStart) .Where(subOp => subOp.DateStart <= o.DateStart)
.Select(subOp => subOp.DurationHours) .Select(subOp => subOp.DurationHours)
.Sum(), .Sum(),
@ -528,21 +529,38 @@ public class WellOperationRepository : IWellOperationRepository
.Min(subOp => subOp.DateStart)) .Min(subOp => subOp.DateStart))
.TotalDays, .TotalDays,
IdUser = o.IdUser, IdUser = o.IdUser,
LastUpdateDate = o.LastUpdateDate.ToOffset(TimeSpan.FromHours(timezone.Hours)) LastUpdateDate = o.LastUpdateDate,
}); });
if (request.SortFields?.Any() == true) if (request.SortFields?.Any() == true)
{ {
dtos = dtos.SortBy(request.SortFields); dtos = dtos.SortBy(request.SortFields);
} }
else
{
dtos = dtos
.OrderBy(e => e.DateStart)
.ThenBy(e => e.DepthEnd)
.ThenBy(e => e.Id);
}
return dtos; dtos = dtos
.OrderBy(e => e.DateStart)
.ThenBy(e => e.DepthEnd)
.ThenBy(e => e.Id);
if (request.Skip.HasValue)
dtos = dtos.Skip(request.Skip.Value);
if (request.Take.HasValue)
dtos = dtos.Take(request.Take.Value);
return dtos.AsNoTracking();
}
private WellOperationDto Convert(WellOperationDto dto)
{
var timezone = wellService.GetTimezone(dto.IdWell);
var timezoneOffset = TimeSpan.FromHours(timezone.Hours);
var dtoWithRemoteDateTime = dto.Adapt<WellOperationDto>();
dtoWithRemoteDateTime.DateStart = dto.DateStart.ToOffset(TimeSpan.FromHours(timezoneOffset.Hours));
dtoWithRemoteDateTime.LastUpdateDate = dto.LastUpdateDate?.ToOffset(TimeSpan.FromHours(timezoneOffset.Hours));
return dtoWithRemoteDateTime;
} }
} }

View File

@ -75,6 +75,8 @@ public class WellOperationImportService : IWellOperationImportService
throw new FileFormatException($"Лист '{sheet.Name}'. Строка '{row.Number}' некорректная длительность операции"); throw new FileFormatException($"Лист '{sheet.Name}'. Строка '{row.Number}' некорректная длительность операции");
var timezone = wellService.GetTimezone(idWell); var timezone = wellService.GetTimezone(idWell);
var timezoneOffset = TimeSpan.FromHours(timezone.Hours);
var wellOperation = new WellOperationDto var wellOperation = new WellOperationDto
{ {
IdWell = idWell, IdWell = idWell,
@ -85,7 +87,7 @@ public class WellOperationImportService : IWellOperationImportService
CategoryInfo = row.CategoryInfo, CategoryInfo = row.CategoryInfo,
DepthStart = row.DepthStart, DepthStart = row.DepthStart,
DepthEnd = row.DepthEnd, DepthEnd = row.DepthEnd,
DateStart = row.Date.ToUtcDateTimeOffset(timezone.Hours).ToRemoteDateTime(timezone.Hours), DateStart = new DateTimeOffset(row.Date, timezoneOffset),
DurationHours = row.Duration, DurationHours = row.Duration,
Comment = row.Comment Comment = row.Comment
}; };

View File

@ -4,6 +4,7 @@ using AsbCloudWebApi.IntegrationTests.Clients;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using AsbCloudApp.Requests; using AsbCloudApp.Requests;
using AsbCloudWebApi.IntegrationTests.Data;
using Refit; using Refit;
using Xunit; using Xunit;
@ -30,7 +31,7 @@ public class WellOperationControllerTest : BaseIntegrationTest
DepthEnd = 20.0, DepthEnd = 20.0,
Day = 0.0, Day = 0.0,
NptHours = 0.0, NptHours = 0.0,
DateStart = new DateTimeOffset(new DateTime(2023, 02, 03, 1, 0, 0, DateTimeKind.Unspecified)), DateStart = new DateTimeOffset(new DateTime(2023, 1, 10), TimeSpan.FromHours(Defaults.Wells[0].Timezone.Hours)),
DurationHours = 1.0, DurationHours = 1.0,
Comment = "1", Comment = "1",
IdUser = 1, IdUser = 1,
@ -58,7 +59,7 @@ public class WellOperationControllerTest : BaseIntegrationTest
IdPlan = null, IdPlan = null,
IdUser = 1, IdUser = 1,
IdWellSectionType = 1, IdWellSectionType = 1,
LastUpdateDate = DateTimeOffset.Now, LastUpdateDate = null,
NptHours = 1, NptHours = 1,
WellSectionTypeName = null, WellSectionTypeName = null,
UserName = null UserName = null
@ -218,8 +219,6 @@ public class WellOperationControllerTest : BaseIntegrationTest
public async Task ImportPlanDefaultExcelFileAsync_returns_success() public async Task ImportPlanDefaultExcelFileAsync_returns_success()
{ {
//arrange //arrange
const int timeZoneUtc = 5;
//TODO: вынести в метод расширения. Сделать когда доберёмся до рефакторинга операций по скважине //TODO: вынести в метод расширения. Сделать когда доберёмся до рефакторинга операций по скважине
var resourceName = Assembly.GetExecutingAssembly() var resourceName = Assembly.GetExecutingAssembly()
.GetManifestResourceNames() .GetManifestResourceNames()
@ -246,6 +245,6 @@ public class WellOperationControllerTest : BaseIntegrationTest
//assert //assert
Assert.NotNull(response.Content); Assert.NotNull(response.Content);
Assert.Equal(4, response.Content.Count()); Assert.Equal(4, response.Content.Count());
Assert.True(response.Content.All(w => Math.Abs(w.DateStart.Offset.Hours - timeZoneUtc) < 0.1)); Assert.True(response.Content.All(w => Math.Abs(w.DateStart.Offset.Hours - Defaults.Wells[0].Timezone.Hours) < 0.1));
} }
} }

View File

@ -117,7 +117,7 @@ namespace AsbCloudWebApi.Tests.Services.WellOperationExport
wellOperationImportTemplateService = new WellOperationImportTemplateService(); wellOperationImportTemplateService = new WellOperationImportTemplateService();
wellOperationExportService = new WellOperationExportService(wellOperationRepository, wellService, wellOperationImportTemplateService); wellOperationExportService = new WellOperationExportService(wellOperationRepository, wellService, wellOperationImportTemplateService);
wellOperationImportService = new WellOperationImportService(wellOperationRepository); wellOperationImportService = new WellOperationImportService(wellService, wellOperationRepository);
wellOperationDefaultExcelParser = new WellOperationDefaultExcelParser(); wellOperationDefaultExcelParser = new WellOperationDefaultExcelParser();
this.output = output; this.output = output;
} }

View File

@ -285,7 +285,6 @@ namespace AsbCloudWebApi.Controllers
foreach (var wellOperation in wellOperations) foreach (var wellOperation in wellOperations)
{ {
wellOperation.IdWell = idWell; wellOperation.IdWell = idWell;
wellOperation.LastUpdateDate = DateTimeOffset.UtcNow;
wellOperation.IdUser = User.GetUserId(); wellOperation.IdUser = User.GetUserId();
wellOperation.IdType = idType; wellOperation.IdType = idType;
} }
@ -338,7 +337,6 @@ namespace AsbCloudWebApi.Controllers
value.IdWell = idWell; value.IdWell = idWell;
value.Id = idOperation; value.Id = idOperation;
value.LastUpdateDate = DateTimeOffset.UtcNow;
value.IdUser = User.GetUserId(); value.IdUser = User.GetUserId();
var validationResult = await operationRepository.ValidateWithDbAsync(new[] { value }, token); var validationResult = await operationRepository.ValidateWithDbAsync(new[] { value }, token);