forked from ddrilling/AsbCloudServer
Фикс сервисов
1. Устранение багов выявленных при тестировании 2. Изменение имён методов в сервисе суточных отчётов 3. Фикс получения фиктивных суточных отчётов 4. Фикс шаблона 5. Правки в контроллере 6. Фикс в репозитории. Приведение к utc доа выполнения запроса 7. Покрытие сервиса тестами
This commit is contained in:
parent
968596b4bf
commit
1bda2d5b77
@ -3,42 +3,36 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.DailyReport;
|
||||
using AsbCloudApp.Data.DailyReport.Blocks;
|
||||
using AsbCloudApp.Requests;
|
||||
|
||||
namespace AsbCloudApp.Services.DailyReport;
|
||||
|
||||
/// <summary>
|
||||
/// Суточные отчёты
|
||||
/// </summary>
|
||||
public interface IDailyReportService
|
||||
{
|
||||
/// <summary>
|
||||
/// Создать отчёт
|
||||
/// Обновить или создать суточный отчёт
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="dateStart"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> InsertAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Обновить блок
|
||||
/// </summary>
|
||||
/// <param name="idDailyReport"></param>
|
||||
/// <param name="dateDailyReport"></param>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="editableBlock"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <typeparam name="TBlock"></typeparam>
|
||||
/// <param name="idWell"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateBlockAsync<TBlock>(int idDailyReport, int idUser, TBlock editableBlock, CancellationToken cancellationToken)
|
||||
where TBlock : EditableBlock;
|
||||
Task<int> UpdateOrInsertAsync<TBlock>(int idWell, DateTime dateDailyReport, int idUser, TBlock editableBlock,
|
||||
CancellationToken cancellationToken)
|
||||
where TBlock : ItemInfoDto;
|
||||
|
||||
/// <summary>
|
||||
/// Получить сформированный суточный отчёт
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="dateStart"></param>
|
||||
/// <param name="dateDailyReport"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<DailyReportDto> GetAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken);
|
||||
Task<DailyReportDto> GetAsync(int idWell, DateTime dateDailyReport, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Получить список суточных отчётов по скважине
|
||||
@ -47,8 +41,7 @@ public interface IDailyReportService
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<PaginationContainer<DailyReportDto>> GetAsync(int idWell, FileReportRequest request,
|
||||
CancellationToken cancellationToken);
|
||||
Task<PaginationContainer<DailyReportDto>> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат по которым возможно сформировать суточный отчёты
|
||||
|
@ -32,10 +32,16 @@ public class DailyReportRepository : CrudRepositoryBase<DailyReportDto, DailyRep
|
||||
var query = GetQuery().Where(d => d.IdWell == idWell);
|
||||
|
||||
if (request.GeDate.HasValue)
|
||||
query = query.Where(d => d.Date >= request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc));
|
||||
{
|
||||
var geDate = request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
|
||||
query = query.Where(d => d.Date >= geDate);
|
||||
}
|
||||
|
||||
if (request.LeDate.HasValue)
|
||||
query = query.Where(d => d.Date <= request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc));
|
||||
{
|
||||
var leDate = request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
|
||||
query = query.Where(d => d.Date <= leDate);
|
||||
}
|
||||
|
||||
if (request.SortFields?.Any() == true)
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ public class DailyReportExportService : IDailyReportExportService
|
||||
private const int columnTimeBalanceDurationFact = 4;
|
||||
private const int columnTimeBalanceReasonDeviation = 8;
|
||||
private const int columnTimeBalanceDrillingDeviationPerSection = 10;
|
||||
private const int columnTimeBalanceDrillingDeviationPerDaily = 11;
|
||||
private const int columnTimeBalanceDrillingDeviationPerDay = 11;
|
||||
|
||||
private const int columnSheduleDriller = 3;
|
||||
private const int columnSheduleShiftStart = 7;
|
||||
@ -56,10 +56,9 @@ public class DailyReportExportService : IDailyReportExportService
|
||||
private const string cellContractor = "C3";
|
||||
private const string cellDeposit = "C5";
|
||||
private const string cellCluster = "C6";
|
||||
private const string cellWellName = "C7";
|
||||
private const string cellWellCaption = "C7";
|
||||
private const string cellWellType = "C8";
|
||||
private const string cellDateStart = "C12";
|
||||
private const string cellDateEnd = "D12";
|
||||
private const string cellDate = "C12";
|
||||
private const string cellDepthStart = "C13";
|
||||
private const string cellDepthEnd = "D13";
|
||||
|
||||
@ -95,7 +94,7 @@ public class DailyReportExportService : IDailyReportExportService
|
||||
|
||||
var stream = await GenerateFileAsync(dailyReport, cancellationToken);
|
||||
|
||||
var fileName = $"Суточный_рапорт_по_скважине_{dailyReport.WellName}_куст_{dailyReport.Cluster}_от_{dailyReport.DateStart:yy-MM-dd}.xlsx";
|
||||
var fileName = $"Суточный_рапорт_по_скважине_{dailyReport.WellCaption}_куст_{dailyReport.Cluster}_от_{dailyReport.Date:yy-MM-dd}.xlsx";
|
||||
|
||||
return (fileName, stream);
|
||||
}
|
||||
@ -127,10 +126,9 @@ public class DailyReportExportService : IDailyReportExportService
|
||||
sheet.Cell(cellContractor).Value = dailyReport.Contractor;
|
||||
sheet.Cell(cellDeposit).Value = dailyReport.Deposit;
|
||||
sheet.Cell(cellCluster).Value = dailyReport.Cluster;
|
||||
sheet.Cell(cellWellName).Value = dailyReport.WellName;
|
||||
sheet.Cell(cellWellCaption).Value = dailyReport.WellCaption;
|
||||
sheet.Cell(cellWellType).Value = dailyReport.WellType;
|
||||
sheet.Cell(cellDateStart).Value = dailyReport.DateStart;
|
||||
sheet.Cell(cellDateEnd).Value = dailyReport.DateEnd;
|
||||
sheet.Cell(cellDate).Value = dailyReport.Date;
|
||||
sheet.Cell(cellDepthStart).Value = dailyReport.DepthStart;
|
||||
sheet.Cell(cellDepthEnd).Value = dailyReport.DepthEnd;
|
||||
|
||||
@ -163,18 +161,18 @@ public class DailyReportExportService : IDailyReportExportService
|
||||
|
||||
foreach (var wellOperation in timeBalanceBlock.WellOperations.OrderBy(w => w.IdWellOperation))
|
||||
{
|
||||
sheet.Cell(rowCurrent, columnTimeBalanceDurationPlan).Value = wellOperation.DurationHours?.Plan;
|
||||
sheet.Cell(rowCurrent, columnTimeBalanceDurationFact).Value = wellOperation.DurationHours?.Fact;
|
||||
sheet.Cell(rowCurrent, columnTimeBalanceDurationPlan).Value = wellOperation.DurationHours.Plan;
|
||||
sheet.Cell(rowCurrent, columnTimeBalanceDurationFact).Value = wellOperation.DurationHours.Fact;
|
||||
sheet.Cell(rowCurrent, columnTimeBalanceReasonDeviation).Value = wellOperation.ReasonDeviation;
|
||||
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerSection).Value = wellOperation.DrillingDeviationPerSection;
|
||||
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerDaily).Value = wellOperation.DrillingDeviationPerDaily;
|
||||
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerDay).Value = wellOperation.DrillingDeviationPerDay;
|
||||
|
||||
rowCurrent++;
|
||||
}
|
||||
|
||||
sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.SectionName;
|
||||
sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepthPlan;
|
||||
sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepthFact;
|
||||
sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepth.Plan;
|
||||
sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepth.Fact;
|
||||
sheet.Cell(cellTimeBalanceBlockWellOperationSlipsTimeCount).Value = timeBalanceBlock.WellOperationSlipsTimeCount;
|
||||
}
|
||||
|
||||
|
@ -52,31 +52,16 @@ public class DailyReportService : IDailyReportService
|
||||
this.detectedOperationService = detectedOperationService;
|
||||
}
|
||||
|
||||
public async Task<int> InsertAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken)
|
||||
{
|
||||
if (await dailyReportRepository.AnyAsync(idWell, dateStart, cancellationToken))
|
||||
throw new ArgumentInvalidException(nameof(dateStart), "Суточный отчёт уже существует");
|
||||
|
||||
var dailyReport = new DailyReportDto
|
||||
{
|
||||
IdWell = idWell,
|
||||
DateStart = dateStart,
|
||||
};
|
||||
|
||||
return await dailyReportRepository.InsertAsync(dailyReport, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> UpdateBlockAsync<TBlock>(int idDailyReport, int idUser, TBlock editableBlock,
|
||||
public async Task<int> UpdateOrInsertAsync<TBlock>(int idWell, DateTime dateDailyReport, int idUser, TBlock editableBlock,
|
||||
CancellationToken cancellationToken)
|
||||
where TBlock : EditableBlock
|
||||
where TBlock : ItemInfoDto
|
||||
{
|
||||
var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idDailyReport, cancellationToken)
|
||||
?? throw new ArgumentInvalidException(nameof(idDailyReport), $"Суточный отчёт с Id: {idDailyReport} не найден");
|
||||
|
||||
editableBlock.IdUser = idUser;
|
||||
|
||||
editableBlock.DateLastUpdate = DateTime.UtcNow;
|
||||
dailyReport.DateLastUpdate = DateTime.UtcNow;
|
||||
var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateDailyReport, cancellationToken) ??
|
||||
new DailyReportDto
|
||||
{
|
||||
IdWell = idWell,
|
||||
Date = dateDailyReport
|
||||
};
|
||||
|
||||
switch (editableBlock)
|
||||
{
|
||||
@ -89,39 +74,46 @@ public class DailyReportService : IDailyReportService
|
||||
case SignBlockDto signBlock:
|
||||
dailyReport.SignBlock = signBlock;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Unexpected type of editableBlock");
|
||||
}
|
||||
|
||||
editableBlock.IdUser = idUser;
|
||||
editableBlock.LastUpdateDate = DateTime.UtcNow;
|
||||
|
||||
dailyReport.DateLastUpdate = DateTime.UtcNow;
|
||||
|
||||
if (dailyReport.Id == 0)
|
||||
return await dailyReportRepository.InsertAsync(dailyReport, cancellationToken);
|
||||
|
||||
return await dailyReportRepository.UpdateAsync(dailyReport, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<DailyReportDto> GetAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken)
|
||||
public async Task<DailyReportDto> GetAsync(int idWell, DateTime dateDailyReport, CancellationToken cancellationToken)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken);
|
||||
|
||||
if (well is null)
|
||||
throw new ArgumentInvalidException($"Скважина с Id: {idWell} не найдена", nameof(idWell));
|
||||
|
||||
var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateStart, cancellationToken) ?? new DailyReportDto
|
||||
var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateDailyReport, cancellationToken) ?? new DailyReportDto
|
||||
{
|
||||
DateStart = dateStart.Date,
|
||||
Date = dateDailyReport.Date,
|
||||
IdWell = well.Id
|
||||
};
|
||||
|
||||
var factWellOperations = await GetFactWellOperationsAsync(idWell, dailyReport.DateStart, dailyReport.DateEnd,
|
||||
cancellationToken);
|
||||
var factWellOperations = (await GetFactWellOperationsAsync(idWell, dailyReport.Date, cancellationToken))
|
||||
.OrderBy(o => o.DateStart)
|
||||
.ThenBy(o => o.DepthStart);
|
||||
|
||||
dailyReport.WellName = well.Caption;
|
||||
dailyReport.WellCaption = well.Caption;
|
||||
dailyReport.WellType = well.WellType;
|
||||
dailyReport.Cluster = well.Cluster;
|
||||
dailyReport.Deposit = well.Deposit;
|
||||
dailyReport.Customer = well.Companies.FirstOrDefault(c => c.IdCompanyType == 1)?.Caption;
|
||||
dailyReport.Contractor = well.Companies.FirstOrDefault(c => c.IdCompanyType == 2)?.Caption;
|
||||
|
||||
if (factWellOperations.Any())
|
||||
{
|
||||
dailyReport.DepthStart = factWellOperations.Min(o => o.DepthStart);
|
||||
dailyReport.DepthEnd = factWellOperations.Max(o => o.DepthEnd);
|
||||
}
|
||||
dailyReport.DepthStart = factWellOperations.FirstOrDefault()?.DepthStart;
|
||||
dailyReport.DepthEnd = factWellOperations.LastOrDefault()?.DepthEnd;
|
||||
|
||||
await UpdateTimeBalanceBlockAsync(dailyReport, factWellOperations, cancellationToken);
|
||||
await UpdateSubsystemBlockAsync(dailyReport, cancellationToken);
|
||||
@ -184,18 +176,18 @@ public class DailyReportService : IDailyReportService
|
||||
{
|
||||
for (var day = result.Skip; day - result.Skip < result.Take && datesRange.To.AddDays(-day) >= datesRange.From; day++)
|
||||
{
|
||||
var dateStart = datesRange.To.AddDays(-day);
|
||||
var dateDailyReport = datesRange.To.AddDays(-day).Date;
|
||||
|
||||
AddDailyReport(dateStart);
|
||||
AddDailyReport(dateDailyReport);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var day = result.Skip; day - result.Skip < result.Take && datesRange.From.AddDays(day) <= datesRange.To; day++)
|
||||
{
|
||||
var dateStart = datesRange.From.AddDays(day);
|
||||
var dateDailyReport = datesRange.From.AddDays(day).Date;
|
||||
|
||||
AddDailyReport(dateStart);
|
||||
AddDailyReport(dateDailyReport);
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,10 +195,9 @@ public class DailyReportService : IDailyReportService
|
||||
|
||||
return result;
|
||||
|
||||
void AddDailyReport(DateTime dateStart)
|
||||
void AddDailyReport(DateTime date)
|
||||
{
|
||||
var existingDailyReport = existingDailyReports.FirstOrDefault(d => d.IdWell == idWell &&
|
||||
d.DateStart == dateStart);
|
||||
var existingDailyReport = existingDailyReports.FirstOrDefault(d => d.IdWell == idWell && d.Date == date);
|
||||
|
||||
if (existingDailyReport is not null)
|
||||
{
|
||||
@ -216,7 +207,7 @@ public class DailyReportService : IDailyReportService
|
||||
|
||||
dailyReports.Add(new DailyReportDto
|
||||
{
|
||||
DateStart = dateStart,
|
||||
Date = date,
|
||||
IdWell = well.Id
|
||||
});
|
||||
}
|
||||
@ -224,16 +215,18 @@ public class DailyReportService : IDailyReportService
|
||||
|
||||
public async Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var factOperations = await GetFactWellOperationsAsync(idWell, null, null,
|
||||
cancellationToken);
|
||||
var factOperations = await GetFactWellOperationsAsync(idWell, null, cancellationToken);
|
||||
|
||||
if (!factOperations.Any())
|
||||
return null;
|
||||
|
||||
var minDateStart = factOperations.Min(o => o.DateStart);
|
||||
var maxDateStart = factOperations.Max(o => o.DateStart);
|
||||
|
||||
return new DatesRangeDto
|
||||
{
|
||||
From = factOperations.Min(o => o.DateStart).Date,
|
||||
To = factOperations.Max(o => o.DateStart).Date
|
||||
From = minDateStart.Date.AddDays(1) <= DateTime.UtcNow ? minDateStart : DateTime.UtcNow.Date.AddDays(-1),
|
||||
To = maxDateStart.AddDays(1) <= DateTime.UtcNow ? maxDateStart : DateTime.UtcNow.Date.AddDays(-1)
|
||||
};
|
||||
}
|
||||
|
||||
@ -241,24 +234,24 @@ public class DailyReportService : IDailyReportService
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
const int idWellOperationSlipsTime = 5011;
|
||||
|
||||
|
||||
if (dailyReport.TimeBalanceBlock is not null)
|
||||
{
|
||||
dailyReport.TimeBalanceBlock.SectionName = wellOperationRepository.GetSectionTypes()
|
||||
.FirstOrDefault(s => s.Id == dailyReport.TimeBalanceBlock.IdSection)?.Caption;
|
||||
|
||||
|
||||
dailyReport.TimeBalanceBlock.WellOperationSlipsTimeCount = (await detectedOperationService.GetAsync(
|
||||
new DetectedOperationRequest
|
||||
{
|
||||
IdsCategories = new[] { idWellOperationSlipsTime },
|
||||
IdWell = dailyReport.IdWell,
|
||||
GtDate = dailyReport.DateStart,
|
||||
LtDate = dailyReport.DateEnd
|
||||
GtDate = dailyReport.Date,
|
||||
LtDate = dailyReport.Date.AddHours(24)
|
||||
}, cancellationToken))?.Stats.Sum(s => s.Count);
|
||||
|
||||
dailyReport.TimeBalanceBlock.WellDepthFact = factWellOperations
|
||||
dailyReport.TimeBalanceBlock.WellDepth.Fact = factWellOperations
|
||||
.Where(o => o.IdWellSectionType == dailyReport.TimeBalanceBlock.IdSection)
|
||||
.Sum(o => o.DepthEnd = o.DepthStart);
|
||||
.Sum(o => o.DepthEnd - o.DepthStart);
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,9 +260,9 @@ public class DailyReportService : IDailyReportService
|
||||
var trajectory = (await trajectoryFactRepository.GetAsync(new TrajectoryGeoFactRequest
|
||||
{
|
||||
IdWell = dailyReport.IdWell,
|
||||
GeDate = dailyReport.DateStart,
|
||||
LeDate = dailyReport.DateEnd
|
||||
}, cancellationToken)).LastOrDefault();
|
||||
GeDate = dailyReport.Date,
|
||||
LeDate = dailyReport.Date.AddHours(24)
|
||||
}, cancellationToken)).MaxBy(t => t.WellboreDepth);
|
||||
|
||||
dailyReport.TrajectoryBlock = new TrajectoryBlockDto
|
||||
{
|
||||
@ -281,7 +274,7 @@ public class DailyReportService : IDailyReportService
|
||||
}
|
||||
|
||||
private async Task AddScheduleBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) =>
|
||||
dailyReport.ScheduleBlock = (await scheduleRepository.GetAsync(dailyReport.IdWell, dailyReport.DateStart, cancellationToken))
|
||||
dailyReport.ScheduleBlock = (await scheduleRepository.GetAsync(dailyReport.IdWell, dailyReport.Date, cancellationToken))
|
||||
.Select(s => new ScheduleRecordDto
|
||||
{
|
||||
ShiftStart = s.ShiftStart,
|
||||
@ -299,13 +292,13 @@ public class DailyReportService : IDailyReportService
|
||||
|
||||
async Task<IEnumerable<SubsystemRecordDto>> GetSubsystemsAsync()
|
||||
{
|
||||
var modules = new List<SubsystemRecordDto>();
|
||||
var subsystems = new List<SubsystemRecordDto>();
|
||||
|
||||
var statSubsystemOperationTimePerDaily = (await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest
|
||||
var statSubsystemOperationTimePerDay = (await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest
|
||||
{
|
||||
IdWell = dailyReport.IdWell,
|
||||
GtDate = dailyReport.DateStart,
|
||||
LtDate = dailyReport.DateEnd
|
||||
GtDate = dailyReport.Date,
|
||||
LtDate = dailyReport.Date.AddHours(24)
|
||||
}, cancellationToken)).Select(s =>
|
||||
{
|
||||
var subsystemRecord = s.Adapt<SubsystemRecordDto>();
|
||||
@ -325,21 +318,21 @@ public class DailyReportService : IDailyReportService
|
||||
return subsystemRecord;
|
||||
});
|
||||
|
||||
modules.AddRange(statSubsystemOperationTimePerDaily);
|
||||
modules.AddRange(statSubsystemOperationTimePerWell);
|
||||
subsystems.AddRange(statSubsystemOperationTimePerDay);
|
||||
subsystems.AddRange(statSubsystemOperationTimePerWell);
|
||||
|
||||
if (dailyReport.SubsystemBlock?.Subsystems != null && dailyReport.SubsystemBlock.Subsystems.Any())
|
||||
modules.AddRange(dailyReport.SubsystemBlock.Subsystems);
|
||||
subsystems.AddRange(dailyReport.SubsystemBlock.Subsystems);
|
||||
|
||||
return modules;
|
||||
return subsystems.OrderBy(s => s.SubsystemName);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AddProcessMapWellDrillingBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
|
||||
{
|
||||
dailyReport.ProcessMapWellDrillingBlock = (await processMapReportWellDrillingService.GetAsync(dailyReport.IdWell,
|
||||
cancellationToken)).Where(p => p.DateStart >= dailyReport.DateStart &&
|
||||
p.DateStart <= dailyReport.DateEnd)
|
||||
cancellationToken)).Where(p => p.DateStart >= dailyReport.Date &&
|
||||
p.DateStart <= dailyReport.Date.AddHours(24))
|
||||
.GroupBy(p => p.DrillingMode)
|
||||
.Select(g => new ProcessMapWellDrillingRecordDto
|
||||
{
|
||||
@ -354,7 +347,7 @@ public class DailyReportService : IDailyReportService
|
||||
});
|
||||
}
|
||||
|
||||
private void AddFactWellOperationBlock(DailyReportDto dailyReport, IEnumerable<WellOperationDto> factWellOperations)
|
||||
private static void AddFactWellOperationBlock(DailyReportDto dailyReport, IEnumerable<WellOperationDto> factWellOperations)
|
||||
{
|
||||
const int idWellOperationCategoryDrilling = 4001;
|
||||
|
||||
@ -373,13 +366,12 @@ public class DailyReportService : IDailyReportService
|
||||
};
|
||||
}
|
||||
|
||||
private Task<IEnumerable<WellOperationDto>> GetFactWellOperationsAsync(int idWell, DateTime? dailyReportDateStart,
|
||||
DateTime? dailyReportDateEnd, CancellationToken cancellationToken) =>
|
||||
private Task<IEnumerable<WellOperationDto>> GetFactWellOperationsAsync(int idWell, DateTime? dateDailyReport, CancellationToken cancellationToken) =>
|
||||
wellOperationRepository.GetAsync(new WellOperationRequest
|
||||
{
|
||||
IdWell = idWell,
|
||||
OperationType = WellOperation.IdOperationTypeFact,
|
||||
GeDate = dailyReportDateStart,
|
||||
LtDate = dailyReportDateEnd
|
||||
GeDate = dateDailyReport,
|
||||
LtDate = dateDailyReport?.AddHours(24)
|
||||
}, cancellationToken);
|
||||
}
|
Binary file not shown.
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
@ -6,11 +8,15 @@ using AsbCloudApp.Data.DailyReport;
|
||||
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using AsbCloudApp.Data.ProcessMaps.Report;
|
||||
using AsbCloudApp.Data.Subsystems;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||
using AsbCloudApp.Services.Subsystems;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.DailyReport;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
@ -20,10 +26,169 @@ namespace AsbCloudWebApi.Tests.Services;
|
||||
public class DailyReportServiceTest
|
||||
{
|
||||
private const int idDailyReport = 1;
|
||||
private const int idWell = 2;
|
||||
private const int idUser = 3;
|
||||
private const int idWell = 2;
|
||||
|
||||
private readonly DateTime dateStart = new DateOnly(2023, 10, 26).ToDateTime(TimeOnly.MinValue);
|
||||
private readonly DateTime dateDailyReport = new DateOnly(2023, 10, 26).ToDateTime(TimeOnly.MinValue);
|
||||
|
||||
private readonly SubsystemBlockDto fakeSubsystemBlock = new()
|
||||
{
|
||||
IdUser = idUser,
|
||||
WellBore = 999,
|
||||
MeasurementsPerDay = 999,
|
||||
TotalRopPlan = 999,
|
||||
Comment = "Увеличить обороты",
|
||||
Subsystems = new[]
|
||||
{
|
||||
new SubsystemRecordDto
|
||||
{
|
||||
SubsystemName = "АвтоСПО",
|
||||
IdTimeInterval = 2,
|
||||
UsedTimeHours = 24,
|
||||
SumDepthInterval = 1500,
|
||||
KUsage = 100
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private readonly SignBlockDto fakeSignBlock = new()
|
||||
{
|
||||
IdUser = idUser,
|
||||
DrillingMaster = new SignRecordDto
|
||||
{
|
||||
Name = "Иван",
|
||||
Patronymic = "Иванович",
|
||||
Surname = "Иванов"
|
||||
},
|
||||
Supervisor = new SignRecordDto()
|
||||
{
|
||||
Name = "Илья",
|
||||
Patronymic = "Ильич",
|
||||
Surname = "Бурилов"
|
||||
}
|
||||
};
|
||||
|
||||
private readonly TimeBalanceBlockDto fakeTimeBalanceBlock = new()
|
||||
{
|
||||
IdUser = idUser,
|
||||
IdSection = 1,
|
||||
WellDepth = new PlanFactDto<double?>
|
||||
{
|
||||
Plan = 2000
|
||||
},
|
||||
WellOperations = new[]
|
||||
{
|
||||
new TimeBalanceRecordDto
|
||||
{
|
||||
IdWellOperation = 1,
|
||||
DurationHours = new PlanFactDto<double?>
|
||||
{
|
||||
Fact = 100,
|
||||
Plan = 150,
|
||||
},
|
||||
DrillingDeviationPerSection = 90,
|
||||
DrillingDeviationPerDay = 100,
|
||||
ReasonDeviation = "Отклонение"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private readonly DetectedOperationListDto fakeWellOperationSlipsTime = new()
|
||||
{
|
||||
Stats = new[]
|
||||
{
|
||||
new DetectedOperationDrillersStatDto
|
||||
{
|
||||
Count = 40
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private readonly ProcessMapReportWellDrillingDto fakeProcessMapReportWellDrilling = new()
|
||||
{
|
||||
DrillingMode = "Ротор",
|
||||
DateStart = new DateTime(2023, 10, 26),
|
||||
DeltaDepth = 500,
|
||||
Rop = new PlanFactDto<double?>
|
||||
{
|
||||
Plan = 300,
|
||||
Fact = 500
|
||||
},
|
||||
MechDrillingHours = 100
|
||||
};
|
||||
|
||||
private readonly WellSectionTypeDto fakeSectionType = new()
|
||||
{
|
||||
Id = 1,
|
||||
Caption = "Пилотный ствол",
|
||||
};
|
||||
|
||||
private readonly TrajectoryGeoFactDto fakeLastFactTrajectory = new()
|
||||
{
|
||||
WellboreDepth = 100,
|
||||
VerticalDepth = 150,
|
||||
ZenithAngle = 3,
|
||||
AzimuthGeo = 5
|
||||
};
|
||||
|
||||
private readonly CompanyDto fakeCustomer = new()
|
||||
{
|
||||
Caption = "Тестовый заказчик",
|
||||
IdCompanyType = 1
|
||||
};
|
||||
|
||||
private readonly CompanyDto fakeContractor = new()
|
||||
{
|
||||
Caption = "Тестовый подрядчик",
|
||||
IdCompanyType = 2
|
||||
};
|
||||
|
||||
private readonly WellOperationDto fakeFirstFactWellOperation = new()
|
||||
{
|
||||
IdWell = idWell,
|
||||
IdParentCategory = 4001,
|
||||
IdWellSectionType = 1,
|
||||
CategoryName = "Механическое. бурение",
|
||||
DateStart = new DateTime(2023, 10, 26),
|
||||
DepthStart = 80,
|
||||
DepthEnd = 150,
|
||||
DurationHours = 8,
|
||||
};
|
||||
|
||||
private readonly WellOperationDto fakeLastFactWellOperation = new()
|
||||
{
|
||||
IdWell = idWell,
|
||||
CategoryName = "Механическое. бурение",
|
||||
IdWellSectionType = 1,
|
||||
IdParentCategory = 4001,
|
||||
DateStart = new DateTime(2023, 10, 26),
|
||||
DepthStart = 150,
|
||||
DepthEnd = 200,
|
||||
DurationHours = 8,
|
||||
};
|
||||
|
||||
private readonly ScheduleDto fakeShedule = new()
|
||||
{
|
||||
IdWell = idWell,
|
||||
ShiftStart = new TimeDto(1),
|
||||
ShiftEnd = new TimeDto(5),
|
||||
DrillStart = new DateTime(2023, 01, 26),
|
||||
DrillEnd = new DateTime(2023, 12, 26),
|
||||
Driller = new()
|
||||
{
|
||||
Name = "Иван",
|
||||
Surname = "Иванов",
|
||||
Patronymic = "Бурила"
|
||||
}
|
||||
};
|
||||
|
||||
private readonly SubsystemStatDto fakeStatSubsystemOperationTimePerDay = new()
|
||||
{
|
||||
SubsystemName = "АПД",
|
||||
SumDepthInterval = 250,
|
||||
UsedTimeHours = 200,
|
||||
KUsage = 30
|
||||
};
|
||||
|
||||
private readonly IWellService wellServiceMock = Substitute.For<IWellService>();
|
||||
private readonly ITrajectoryFactRepository trajectoryFactRepositoryMock = Substitute.For<ITrajectoryFactRepository>();
|
||||
@ -33,18 +198,30 @@ public class DailyReportServiceTest
|
||||
private readonly ISubsystemOperationTimeService subsystemOperationTimeServiceMock = Substitute.For<ISubsystemOperationTimeService>();
|
||||
private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingServiceMock = Substitute.For<IProcessMapReportWellDrillingService>();
|
||||
private readonly IDetectedOperationService detectedOperationServiceMock = Substitute.For<IDetectedOperationService>();
|
||||
|
||||
|
||||
private readonly DailyReportService dailyReportService;
|
||||
|
||||
private readonly DailyReportDto fakeDailyReport;
|
||||
private readonly WellDto fakeWell;
|
||||
|
||||
public DailyReportServiceTest()
|
||||
{
|
||||
fakeDailyReport = new()
|
||||
fakeDailyReport = new DailyReportDto
|
||||
{
|
||||
Id = idDailyReport,
|
||||
IdWell = idWell,
|
||||
DateStart = dateStart
|
||||
Date = dateDailyReport,
|
||||
DateLastUpdate = null
|
||||
};
|
||||
|
||||
fakeWell = new WellDto
|
||||
{
|
||||
Id = idWell,
|
||||
Caption = "Тестовое название",
|
||||
WellType = "Горизонтальная",
|
||||
Cluster = "Тестовый куст",
|
||||
Deposit = "Тестовое месторождение",
|
||||
Companies = new[] { fakeCustomer, fakeContractor }
|
||||
};
|
||||
|
||||
dailyReportService = new DailyReportService(wellServiceMock,
|
||||
@ -59,139 +236,276 @@ public class DailyReportServiceTest
|
||||
dailyReportRepositoryMock.InsertAsync(Arg.Any<DailyReportDto>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(idDailyReport);
|
||||
|
||||
dailyReportRepositoryMock.GetOrDefaultAsync(idDailyReport, Arg.Any<CancellationToken>())
|
||||
.Returns(fakeDailyReport);
|
||||
dailyReportRepositoryMock.GetOrDefaultAsync(Arg.Any<int>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(fakeDailyReport);
|
||||
|
||||
dailyReportRepositoryMock.UpdateAsync(Arg.Any<DailyReportDto>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(idDailyReport);
|
||||
|
||||
wellServiceMock.GetOrDefaultAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(fakeWell);
|
||||
|
||||
trajectoryFactRepositoryMock.GetAsync(Arg.Any<TrajectoryGeoFactRequest>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(new[] { fakeLastFactTrajectory });
|
||||
|
||||
wellOperationRepositoryMock.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(new[] { fakeFirstFactWellOperation, fakeLastFactWellOperation });
|
||||
|
||||
wellOperationRepositoryMock.GetSectionTypes()
|
||||
.ReturnsForAnyArgs(new[] { fakeSectionType });
|
||||
|
||||
detectedOperationServiceMock.GetAsync(Arg.Any<DetectedOperationRequest>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(fakeWellOperationSlipsTime);
|
||||
|
||||
subsystemOperationTimeServiceMock.GetStatAsync(Arg.Any<SubsystemOperationTimeRequest>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(new[] { fakeStatSubsystemOperationTimePerDay });
|
||||
|
||||
scheduleRepositoryMock.GetAsync(idWell, dateDailyReport, Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(new[] { fakeShedule });
|
||||
|
||||
processMapReportWellDrillingServiceMock.GetAsync(idWell, Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(new[] { fakeProcessMapReportWellDrilling });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertAsync_ShouldReturn_ExceptionAboutDuplicate()
|
||||
public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedSubsystemBlock()
|
||||
{
|
||||
//arrange
|
||||
dailyReportRepositoryMock.AnyAsync(Arg.Any<int>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(true);
|
||||
|
||||
//act
|
||||
Task Result() => dailyReportService.InsertAsync(idWell, dateStart, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
var exception = await Assert.ThrowsAsync<ArgumentInvalidException>(Result);
|
||||
Assert.Equal("Суточный отчёт уже существует", exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertAsync_ShouldReturn_PositiveId()
|
||||
{
|
||||
//arrange
|
||||
dailyReportRepositoryMock.AnyAsync(Arg.Any<int>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(false);
|
||||
|
||||
//act
|
||||
var result = await dailyReportService.InsertAsync(idWell, dateStart, CancellationToken.None);
|
||||
var result = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport, idUser, fakeSubsystemBlock, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(fakeSubsystemBlock.LastUpdateDate);
|
||||
Assert.NotNull(fakeDailyReport.DateLastUpdate);
|
||||
Assert.Equal(fakeSubsystemBlock.IdUser, idUser);
|
||||
Assert.Equal(fakeDailyReport.SubsystemBlock, fakeSubsystemBlock);
|
||||
Assert.Equal(idDailyReport, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateSubsystemBlock_ShouldReturn_Success()
|
||||
public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedSignBlock()
|
||||
{
|
||||
//arrange
|
||||
var fakeSubsystemBlock = new SubsystemBlockDto
|
||||
{
|
||||
IdUser = idUser,
|
||||
WellBore = 999,
|
||||
MeasurementsPerDay = 999,
|
||||
TotalRopPlan = 999,
|
||||
Comment = "Увеличить обороты",
|
||||
Subsystems = new[]
|
||||
{
|
||||
new SubsystemRecordDto
|
||||
{
|
||||
SubsystemName = "АвтоСПО",
|
||||
IdTimeInterval = 1,
|
||||
UsedTimeHours = 24,
|
||||
SumDepthInterval = 1500,
|
||||
KUsage = 100
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//act
|
||||
var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeSubsystemBlock, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(fakeSubsystemBlock.DateLastUpdate);
|
||||
Assert.NotNull(fakeDailyReport.DateLastUpdate);
|
||||
Assert.Equal(fakeDailyReport.SubsystemBlock, fakeSubsystemBlock);
|
||||
Assert.Equal(idDailyReport, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateSignBlock_ShouldReturn_Success()
|
||||
{
|
||||
//arrange
|
||||
var fakeSignBlock = new SignBlockDto
|
||||
{
|
||||
IdUser = idUser,
|
||||
DrillingMaster = new SignRecordDto()
|
||||
{
|
||||
Name = "Иван",
|
||||
Patronymic = "Иванович",
|
||||
Surname = "Иванов"
|
||||
},
|
||||
Supervisor = new SignRecordDto()
|
||||
{
|
||||
Name = "Илья",
|
||||
Patronymic = "Ильич",
|
||||
Surname = "Бурилов"
|
||||
}
|
||||
};
|
||||
|
||||
//act
|
||||
var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeSignBlock, CancellationToken.None);
|
||||
var result = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport, idUser, fakeSignBlock, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(fakeSignBlock.DateLastUpdate);
|
||||
Assert.NotNull(fakeSignBlock.LastUpdateDate);
|
||||
Assert.NotNull(fakeDailyReport.DateLastUpdate);
|
||||
Assert.Equal(fakeSignBlock.IdUser, idUser);
|
||||
Assert.Equal(fakeDailyReport.SignBlock, fakeSignBlock);
|
||||
Assert.Equal(idDailyReport, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateTimeBalance_ShouldReturn_Success()
|
||||
public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedTimeBalanceBlock()
|
||||
{
|
||||
//arrange
|
||||
var fakeTimeBalanceBlock = new TimeBalanceBlockDto
|
||||
{
|
||||
IdUser = idUser,
|
||||
IdSection = 1,
|
||||
WellDepthPlan = 2000,
|
||||
WellOperations = new[]
|
||||
{
|
||||
new TimeBalanceRecordDto()
|
||||
{
|
||||
DurationHours = new PlanFactDto<double>()
|
||||
{
|
||||
Fact = 100,
|
||||
Plan = 150,
|
||||
},
|
||||
DrillingDeviationPerSection = 90,
|
||||
DrillingDeviationPerDaily = 100,
|
||||
ReasonDeviation = "Отклонение"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//act
|
||||
var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeTimeBalanceBlock, CancellationToken.None);
|
||||
var result = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport, idUser, fakeTimeBalanceBlock,
|
||||
CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(fakeTimeBalanceBlock.DateLastUpdate);
|
||||
Assert.NotNull(fakeTimeBalanceBlock.LastUpdateDate);
|
||||
Assert.NotNull(fakeDailyReport.DateLastUpdate);
|
||||
Assert.Equal(fakeTimeBalanceBlock.IdUser, idUser);
|
||||
Assert.Equal(fakeDailyReport.TimeBalanceBlock, fakeTimeBalanceBlock);
|
||||
Assert.Equal(idDailyReport, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_ShouldReturn_AddedWellInfo()
|
||||
{
|
||||
//act
|
||||
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Equal(result.IdWell, fakeWell.Id);
|
||||
Assert.Equal(result.WellCaption, fakeWell.Caption);
|
||||
Assert.Equal(result.WellType, fakeWell.WellType);
|
||||
Assert.Equal(result.Cluster, fakeWell.Cluster);
|
||||
Assert.Equal(result.Deposit, fakeWell.Deposit);
|
||||
Assert.Equal(result.Customer, fakeCustomer.Caption);
|
||||
Assert.Equal(result.Contractor, fakeContractor.Caption);
|
||||
Assert.Equal(result.DepthStart, fakeFirstFactWellOperation.DepthStart);
|
||||
Assert.Equal(result.DepthEnd, fakeLastFactWellOperation.DepthEnd);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_ShouldReturn_AddedTrajectoryBlock()
|
||||
{
|
||||
//act
|
||||
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Equal(fakeLastFactTrajectory.WellboreDepth, result.TrajectoryBlock.WellboreDepth);
|
||||
Assert.Equal(fakeLastFactTrajectory.VerticalDepth, result.TrajectoryBlock.VerticalDepth);
|
||||
Assert.Equal(fakeLastFactTrajectory.ZenithAngle, result.TrajectoryBlock.ZenithAngle);
|
||||
Assert.Equal(fakeLastFactTrajectory.AzimuthGeo, result.TrajectoryBlock.AzimuthGeo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_ShouldReturn_AddedFactWellOperationBlock()
|
||||
{
|
||||
//act
|
||||
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Equal(16, result.FactWellOperationBlock.SectionDrillingHours);
|
||||
Assert.Single(result.FactWellOperationBlock.WellOperations);
|
||||
|
||||
var wellOperation = result.FactWellOperationBlock.WellOperations.Single();
|
||||
|
||||
Assert.Equal("Механическое. бурение", wellOperation.CategoryName);
|
||||
Assert.Equal(16, wellOperation.DurationHours);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_ShouldReturn_AddedScheduleBlock()
|
||||
{
|
||||
//act
|
||||
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Single(result.ScheduleBlock);
|
||||
|
||||
var sheduleRecord = result.ScheduleBlock.Single();
|
||||
|
||||
Assert.Equal(fakeShedule.ShiftStart, sheduleRecord.ShiftStart);
|
||||
Assert.Equal(fakeShedule.ShiftEnd, sheduleRecord.ShiftEnd);
|
||||
Assert.Equal(fakeShedule.Driller?.Name, sheduleRecord.Name);
|
||||
Assert.Equal(fakeShedule.Driller?.Surname, sheduleRecord.Surname);
|
||||
Assert.Equal(fakeShedule.Driller?.Patronymic, sheduleRecord.Patronymic);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_ShouldReturn_UpdatedTimeBalanceBlock()
|
||||
{
|
||||
//arrange
|
||||
fakeDailyReport.TimeBalanceBlock = fakeTimeBalanceBlock;
|
||||
|
||||
//act
|
||||
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(result.TimeBalanceBlock);
|
||||
Assert.Equal(fakeSectionType.Id, result.TimeBalanceBlock.IdSection);
|
||||
Assert.Equal(fakeSectionType.Caption, result.TimeBalanceBlock.SectionName);
|
||||
Assert.Equal(2000, result.TimeBalanceBlock?.WellDepth.Plan);
|
||||
Assert.Equal(120, result.TimeBalanceBlock?.WellDepth.Fact);
|
||||
Assert.Equal(40, result.TimeBalanceBlock?.WellOperationSlipsTimeCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_ShouldReturn_AddedProcessMapWellDrillingBlock()
|
||||
{
|
||||
//act
|
||||
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Single(result.ProcessMapWellDrillingBlock);
|
||||
|
||||
var processMapWellDrillingRecord = result.ProcessMapWellDrillingBlock.Single();
|
||||
|
||||
Assert.Equal(fakeProcessMapReportWellDrilling.DrillingMode, processMapWellDrillingRecord.DrillingMode);
|
||||
Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Plan, processMapWellDrillingRecord.Rop.Plan);
|
||||
Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Fact, processMapWellDrillingRecord.Rop.Fact);
|
||||
Assert.Equal(fakeProcessMapReportWellDrilling.DeltaDepth, processMapWellDrillingRecord.WellBoreDepth);
|
||||
Assert.Equal(fakeProcessMapReportWellDrilling.MechDrillingHours, processMapWellDrillingRecord.MechDrillingHours);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_ShouldReturn_UpdatedSubsystemBlock()
|
||||
{
|
||||
//arrange
|
||||
fakeDailyReport.SubsystemBlock = fakeSubsystemBlock;
|
||||
|
||||
//act
|
||||
var result = await dailyReportService.GetAsync(idDailyReport, dateDailyReport, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(result.SubsystemBlock);
|
||||
Assert.Equal(3, result.SubsystemBlock?.Subsystems.Count());
|
||||
|
||||
var subsystemRecord0 = result.SubsystemBlock?.Subsystems.ElementAt(0);
|
||||
|
||||
Assert.Equal("АвтоСПО", subsystemRecord0?.SubsystemName);
|
||||
Assert.Equal(2, subsystemRecord0?.IdTimeInterval);
|
||||
Assert.Equal(24, subsystemRecord0?.UsedTimeHours);
|
||||
Assert.Equal(1500, subsystemRecord0?.SumDepthInterval);
|
||||
Assert.Equal(100, subsystemRecord0?.KUsage);
|
||||
|
||||
var subsystemRecord1 = result.SubsystemBlock?.Subsystems.ElementAt(1);
|
||||
|
||||
Assert.Equal(fakeStatSubsystemOperationTimePerDay.SubsystemName, subsystemRecord1?.SubsystemName);
|
||||
Assert.Equal(1, subsystemRecord1?.IdTimeInterval);
|
||||
Assert.Equal(fakeStatSubsystemOperationTimePerDay.UsedTimeHours, subsystemRecord1?.UsedTimeHours);
|
||||
Assert.Equal(fakeStatSubsystemOperationTimePerDay.SumDepthInterval, subsystemRecord1?.SumDepthInterval);
|
||||
Assert.Equal(fakeStatSubsystemOperationTimePerDay.KUsage, subsystemRecord1?.KUsage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_ShouldReturn_FictiveDailyReport()
|
||||
{
|
||||
//act
|
||||
var result = await dailyReportService.GetAsync(idWell, new FileReportRequest(), CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.True((fakeLastFactWellOperation.DateStart - fakeFirstFactWellOperation.DateStart).Days == result.Count);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(FactWellOperationDates))]
|
||||
public async Task GetDatesRangeAsync_ShouldReturn_DateRangeByFactWellOperations(IEnumerable<DateTime> factWellOperationDates)
|
||||
{
|
||||
//arrange
|
||||
wellOperationRepositoryMock.GetAsync(Arg.Any<WellOperationRequest>(), CancellationToken.None)
|
||||
.ReturnsForAnyArgs(factWellOperationDates.Select(dateStart => new WellOperationDto { DateStart = dateStart }));
|
||||
|
||||
//act
|
||||
var result = await dailyReportService.GetDatesRangeAsync(idWell, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(result);
|
||||
Assert.True(result.From <= result.To);
|
||||
Assert.True(result.To < DateTime.UtcNow.Date);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> FactWellOperationDates()
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new DateTime(2023, 11, 1),
|
||||
new DateTime(2023, 11, 9),
|
||||
DateTime.UtcNow
|
||||
}
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new DateTime(2023, 11, 1),
|
||||
new DateTime(2023, 11, 1)
|
||||
}
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
new[]
|
||||
{
|
||||
DateTime.UtcNow,
|
||||
DateTime.UtcNow
|
||||
}
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new DateTime(2023, 11, 1),
|
||||
new DateTime(2023, 11, 9),
|
||||
new DateTime(2023, 11, 11)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.DailyReport;
|
||||
using AsbCloudApp.Data.DailyReport.Blocks;
|
||||
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||
@ -57,39 +56,11 @@ public class DailyReportController : ControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создать суточный отчёт
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="dateStart">Дата формирования суточного отчёта</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> InsertAsync(int idWell, DateOnly dateStart, CancellationToken cancellationToken)
|
||||
{
|
||||
var dateStartToDateTime = dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
|
||||
|
||||
var datesRange = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken);
|
||||
|
||||
if (dateStartToDateTime < datesRange?.From || dateStartToDateTime > datesRange?.To)
|
||||
throw new ArgumentInvalidException("Невозможно сформировать суточный отчёт", nameof(dateStart));
|
||||
|
||||
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||
|
||||
var id = await dailyReportService.InsertAsync(idWell, dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc),
|
||||
cancellationToken);
|
||||
|
||||
return Ok(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновить подпись
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="idDailyReport">Id суточного отчёта</param>
|
||||
/// <param name="dateDailyReport">Дата суточного отчёта</param>
|
||||
/// <param name="signBlock">Обновляемый блок</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
@ -97,14 +68,15 @@ public class DailyReportController : ControllerBase
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public Task<IActionResult> UpdateSignBlockAsync(int idWell, int idDailyReport, SignBlockDto signBlock, CancellationToken cancellationToken) =>
|
||||
UpdateBlockAsync(idWell, idDailyReport, signBlock, cancellationToken);
|
||||
public Task<IActionResult> UpdateSignBlockAsync(int idWell, DateOnly dateDailyReport, SignBlockDto signBlock,
|
||||
CancellationToken cancellationToken) =>
|
||||
UpdateOrInsertAsync(idWell, dateDailyReport, signBlock, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Обновить наработку подсистем
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="idDailyReport">Id суточного отчёта</param>
|
||||
/// <param name="dateDailyReport">Дата суточного отчёта</param>
|
||||
/// <param name="subsystemBlock">Обновляемый блок</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
@ -112,7 +84,7 @@ public class DailyReportController : ControllerBase
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public Task<IActionResult> UpdateSubsystemBlockAsync(int idWell, int idDailyReport, SubsystemBlockDto subsystemBlock,
|
||||
public Task<IActionResult> UpdateSubsystemBlockAsync(int idWell, DateOnly dateDailyReport, SubsystemBlockDto subsystemBlock,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var validSubsystemNames = new[] { "АвтоСПО", "Автопроработка" };
|
||||
@ -121,14 +93,14 @@ public class DailyReportController : ControllerBase
|
||||
throw new ArgumentInvalidException($"Возможно добавить подсистемы с именами {string.Join(", ", validSubsystemNames)}",
|
||||
nameof(subsystemBlock.Subsystems));
|
||||
|
||||
return UpdateBlockAsync(idWell, idDailyReport, subsystemBlock, cancellationToken);
|
||||
return UpdateOrInsertAsync(idWell, dateDailyReport, subsystemBlock, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновить баланс времени
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="idDailyReport">Id суточного отчёта</param>
|
||||
/// <param name="dateDailyReport">Дата суточного отчёта</param>
|
||||
/// <param name="timeBalanceBlock">Обновляемый блок</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
@ -136,7 +108,7 @@ public class DailyReportController : ControllerBase
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public Task<IActionResult> UpdateTimeBalanceBlockAsync(int idWell, int idDailyReport, TimeBalanceBlockDto timeBalanceBlock,
|
||||
public Task<IActionResult> UpdateTimeBalanceBlockAsync(int idWell, DateOnly dateDailyReport, TimeBalanceBlockDto timeBalanceBlock,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var validWellOperationsIds = new[] { 1, 2, 3, 4 };
|
||||
@ -144,13 +116,13 @@ public class DailyReportController : ControllerBase
|
||||
if (timeBalanceBlock.WellOperations.Any(o => !validWellOperationsIds.Contains(o.IdWellOperation)))
|
||||
throw new ArgumentInvalidException($"Возможно добавить операции только с Id: {string.Join(", ", validWellOperationsIds)}",
|
||||
nameof(timeBalanceBlock.WellOperations));
|
||||
|
||||
|
||||
var wellSections = wellOperationRepository.GetSectionTypes();
|
||||
|
||||
if (wellSections.All(s => s.Id != timeBalanceBlock.IdSection))
|
||||
throw new ArgumentInvalidException($"Секция с Id: {timeBalanceBlock.IdSection} не найдена", nameof(timeBalanceBlock.IdSection));
|
||||
|
||||
return UpdateBlockAsync(idWell, idDailyReport, timeBalanceBlock, cancellationToken);
|
||||
return UpdateOrInsertAsync(idWell, dateDailyReport, timeBalanceBlock, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -193,36 +165,37 @@ public class DailyReportController : ControllerBase
|
||||
/// Экспорт суточного рапорта
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="dateStart">Дата формирования суточного отчёта</param>
|
||||
/// <param name="dateDailyReport">Дата формирования суточного отчёта</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{dateStart}")]
|
||||
[HttpGet("{dateDailyReport}")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> ExportAsync(int idWell, DateOnly dateStart, CancellationToken cancellationToken)
|
||||
public async Task<IActionResult> ExportAsync(int idWell, DateOnly dateDailyReport, CancellationToken cancellationToken)
|
||||
{
|
||||
var dateStartToDateTime = dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
|
||||
|
||||
var dateStartToDateTime = dateDailyReport.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
|
||||
|
||||
var datesRange = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken);
|
||||
|
||||
if (dateStartToDateTime < datesRange?.From || dateStartToDateTime > datesRange?.To)
|
||||
throw new ArgumentInvalidException("Невозможно получить суточный отчёт", nameof(dateStart));
|
||||
|
||||
throw new ArgumentInvalidException("Невозможно получить суточный отчёт", nameof(dateDailyReport));
|
||||
|
||||
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||
|
||||
var dailyReport = await dailyReportExportService.ExportAsync(idWell,
|
||||
dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken);
|
||||
dateDailyReport.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken);
|
||||
|
||||
return File(dailyReport.File, "application/octet-stream", dailyReport.FileName);
|
||||
}
|
||||
|
||||
private async Task<IActionResult> UpdateBlockAsync<TBlock>(int idWell, int idDailyReport, TBlock block,
|
||||
private async Task<IActionResult> UpdateOrInsertAsync<TBlock>(int idWell, DateOnly dateDailyReport, TBlock block,
|
||||
CancellationToken cancellationToken)
|
||||
where TBlock : EditableBlock
|
||||
where TBlock : ItemInfoDto
|
||||
{
|
||||
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||
|
||||
var id = await dailyReportService.UpdateBlockAsync(idDailyReport, IdUser, block, cancellationToken);
|
||||
|
||||
var id = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), IdUser,
|
||||
block, cancellationToken);
|
||||
|
||||
return Ok(id);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user