diff --git a/AsbCloudApp/Data/SAUB/DrillTestDto.cs b/AsbCloudApp/Data/SAUB/DrillTestDto.cs index e53ffbbb..acd8ccc6 100644 --- a/AsbCloudApp/Data/SAUB/DrillTestDto.cs +++ b/AsbCloudApp/Data/SAUB/DrillTestDto.cs @@ -24,6 +24,11 @@ namespace AsbCloudApp.Data.SAUB /// public float DepthStart { get; set; } + /// + /// Связанная с drill_test телеметрия + /// + public TelemetryDto Telemetry { get; set; } = null!; + /// /// Параметры теста /// diff --git a/AsbCloudApp/Exceptions/ArgumentInvalidException.cs b/AsbCloudApp/Exceptions/ArgumentInvalidException.cs index 4fe150e3..46057ff0 100644 --- a/AsbCloudApp/Exceptions/ArgumentInvalidException.cs +++ b/AsbCloudApp/Exceptions/ArgumentInvalidException.cs @@ -10,7 +10,7 @@ namespace AsbCloudApp.Exceptions /// /// название аргумента /// - public string ParamName { get; } = string.Empty; + public string[] ParamsNames { get; } = null!; /// /// конструктор @@ -20,7 +20,18 @@ namespace AsbCloudApp.Exceptions public ArgumentInvalidException(string paramName, string message) : base(message) { - ParamName = paramName; + ParamsNames = new string[1] { paramName }; + } + + /// + /// конструктор + /// + /// + /// + public ArgumentInvalidException(string[] paramsNames, string message) + : base(message) + { + ParamsNames = paramsNames; } } } diff --git a/AsbCloudApp/Repositories/IDrillTestRepository.cs b/AsbCloudApp/Repositories/IDrillTestRepository.cs index 18ff0e9b..9c7a2f50 100644 --- a/AsbCloudApp/Repositories/IDrillTestRepository.cs +++ b/AsbCloudApp/Repositories/IDrillTestRepository.cs @@ -1,5 +1,6 @@ using AsbCloudApp.Data.SAUB; using AsbCloudApp.Requests; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -17,7 +18,7 @@ namespace AsbCloudApp.Repositories /// запрос /// /// - Task GetAllAsync(int idTelemetry, FileReportRequest request, CancellationToken cancellationToken); + Task> GetAllAsync(int idTelemetry, FileReportRequest request, CancellationToken cancellationToken); /// /// Получить запись drill_test diff --git a/AsbCloudApp/Requests/AutoGeneratedDailyReportRequest.cs b/AsbCloudApp/Requests/FileReportRequest.cs similarity index 100% rename from AsbCloudApp/Requests/AutoGeneratedDailyReportRequest.cs rename to AsbCloudApp/Requests/FileReportRequest.cs diff --git a/AsbCloudInfrastructure/Repository/DrillTestRepository.cs b/AsbCloudInfrastructure/Repository/DrillTestRepository.cs index 3a16b703..427556a2 100644 --- a/AsbCloudInfrastructure/Repository/DrillTestRepository.cs +++ b/AsbCloudInfrastructure/Repository/DrillTestRepository.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data.SAUB; +using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; @@ -6,6 +7,7 @@ using AsbCloudDb.Model; using Mapster; using Microsoft.EntityFrameworkCore; using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -15,13 +17,15 @@ namespace AsbCloudInfrastructure.Repository public class DrillTestRepository : IDrillTestRepository { private readonly IAsbCloudDbContext db; + private readonly IWellService wellService; - public DrillTestRepository(IAsbCloudDbContext db) + public DrillTestRepository(IAsbCloudDbContext db, IWellService wellService) { this.db = db; + this.wellService = wellService; } - public async Task GetAllAsync(int idTelemetry, FileReportRequest request, CancellationToken cancellationToken) + public async Task> GetAllAsync(int idTelemetry, FileReportRequest request, CancellationToken cancellationToken) { var query = db.DrillTests .Where(d => d.IdTelemetry == idTelemetry) @@ -29,19 +33,17 @@ namespace AsbCloudInfrastructure.Repository if (request.GeDate.HasValue) { - var startDate = new DateTime(request.GeDate.Value.Year, request.GeDate.Value.Month, request.GeDate.Value.Day); - DateTimeOffset startDateUTC = DateTime.SpecifyKind(startDate, DateTimeKind.Utc); + var startDateUTC = new DateTimeOffset(request.GeDate.Value.Year, request.GeDate.Value.Month, request.GeDate.Value.Day, 0, 0, 0, TimeSpan.Zero); query = query.Where(q => q.TimeStampStart >= startDateUTC); } if (request.LeDate.HasValue) { - var finishDate = new DateTime(request.LeDate.Value.Year, request.LeDate.Value.Month, request.LeDate.Value.Day); - DateTimeOffset finishDateUTC = DateTime.SpecifyKind(finishDate, DateTimeKind.Utc); + var finishDateUTC = new DateTimeOffset(request.LeDate.Value.Year, request.LeDate.Value.Month, request.LeDate.Value.Day, 0, 0, 0, TimeSpan.Zero); query = query.Where(q => q.TimeStampStart <= finishDateUTC); } var entities = await query.ToListAsync(cancellationToken); - var dtos = entities.Select(e => e.Adapt()).ToArray(); + var dtos = entities.Select(e => e.Adapt()); return dtos; } @@ -50,14 +52,17 @@ namespace AsbCloudInfrastructure.Repository public async Task GetAsync(int idTelemetry, int id, CancellationToken cancellationToken) { var drillTest = await db.DrillTests - .Where(d => d.IdTelemetry == idTelemetry) .Where(d => d.Id == id) + .Include(d => d.Telemetry) + .Where(d => d.Telemetry.Id == idTelemetry) .FirstOrDefaultAsync(cancellationToken); if (drillTest is null) - throw new Exception($"Drill test with id: {id} and idTelemetry: {idTelemetry} does not exist."); + throw new ArgumentInvalidException(new string[] { nameof(id), nameof(idTelemetry) }, $"Drill test with id: {id} and idTelemetry: {idTelemetry} does not exist."); var dto = drillTest.Adapt(); + dto.TimeStampStart = dto.TimeStampStart.ToRemoteDateTime(dto.Telemetry.TimeZone?.Hours ?? 0); + return dto; } diff --git a/AsbCloudInfrastructure/Services/DrillTestReport/DrillTestReportService.cs b/AsbCloudInfrastructure/Services/DrillTestReport/DrillTestReportService.cs index 6dbc9528..6784ad26 100644 --- a/AsbCloudInfrastructure/Services/DrillTestReport/DrillTestReportService.cs +++ b/AsbCloudInfrastructure/Services/DrillTestReport/DrillTestReportService.cs @@ -1,5 +1,6 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.DrillTestReport; +using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; @@ -33,29 +34,25 @@ namespace AsbCloudInfrastructure.Services.DrillTestReport public async Task<(string fileName, Stream stream)> GenerateAsync(int idWell, int id, CancellationToken cancellationToken) { - var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); - if (telemetry is null) - throw new Exception($"Telemetry with idWell: {idWell} does not exist."); - - var dto = await drillTestRepository.GetAsync(telemetry.Id, id, cancellationToken); - - var timezone = telemetryService.GetTimezone(telemetry.Id); - var remoteDateTime = dto.TimeStampStart.ToRemoteDateTime(timezone.Hours); - dto.TimeStampStart = remoteDateTime; - - var cluster = telemetry.Info?.Cluster ?? "-"; - var deposit = telemetry.Info?.Deposit ?? "-"; - var wellCaption = wellService.GetOrDefault(idWell)!.Caption ?? "-"; - + var well = wellService.GetOrDefault(idWell); + if (well is null) + throw new ArgumentInvalidException(nameof(idWell), $"Well with id: {idWell} does not exist."); + if (well.IdTelemetry is null) + throw new ArgumentInvalidException(nameof(well.IdTelemetry), $"Well with id: {idWell} does not have telemetry."); + var dto = await drillTestRepository.GetAsync(well.IdTelemetry.Value, id, cancellationToken); + var report = new DrillTestReportDataDto() { Data = dto, - Caption = string.Format("Месторождение: {0}, куст: {1}, скважина: {2}", deposit, cluster, wellCaption), + Caption = string.Format("Месторождение: {0}, куст: {1}, скважина: {2}", + well.Deposit ?? "-", + well.Cluster ?? "-", + well.Caption ?? "-"), Date = DateTime.Now, }; - var fileName = string.Format("Drill_test_{0}.xlsx", remoteDateTime.ToString("dd.mm.yyyy_HH_MM_ss")); + var fileName = string.Format("Drill_test_{0}.xlsx", dto.TimeStampStart.ToString("dd.mm.yyyy_HH_MM_ss")); var stream = await drillTestReportMakerService.MakeReportAsync(report, cancellationToken); return (fileName, stream); diff --git a/AsbCloudInfrastructure/XLExtentions.cs b/AsbCloudInfrastructure/XLExtentions.cs index 2f75c820..ca083b6a 100644 --- a/AsbCloudInfrastructure/XLExtentions.cs +++ b/AsbCloudInfrastructure/XLExtentions.cs @@ -92,7 +92,7 @@ internal static class XLExtentions } - internal static IXLCell _SetValue(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS", bool? setAllBorders = true) + internal static IXLCell _SetValue(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS", bool setAllBorders = true) { cell.Value = value; if (setAllBorders == true) diff --git a/AsbCloudWebApi/Controllers/DrillTestReportController.cs b/AsbCloudWebApi/Controllers/DrillTestController.cs similarity index 52% rename from AsbCloudWebApi/Controllers/DrillTestReportController.cs rename to AsbCloudWebApi/Controllers/DrillTestController.cs index c390e09e..bda32d6e 100644 --- a/AsbCloudWebApi/Controllers/DrillTestReportController.cs +++ b/AsbCloudWebApi/Controllers/DrillTestController.cs @@ -1,10 +1,15 @@ using AsbCloudApp.Data; -using AsbCloudApp.Data.AutogeneratedDailyReport; +using AsbCloudApp.Data.DrillTestReport; +using AsbCloudApp.Data.SAUB; +using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; +using AsbCloudWebApi.SignalR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.SignalR; +using System; using System.ComponentModel.DataAnnotations; using System.Net; using System.Threading; @@ -16,18 +21,60 @@ namespace AsbCloudWebApi.Controllers; /// Контроллер для drill_test отчётов /// [ApiController] -[Route("api/well/{idWell}/[controller]")] [Authorize] -public class DrillTestReportController : ControllerBase +public class DrillTestController : ControllerBase { private readonly IDrillTestReportService drillTestReportService; + private readonly IDrillTestRepository drillTestRepository; private readonly IWellService wellService; + private readonly ITelemetryService telemetryService; + private readonly IHubContext telemetryHubContext; - public DrillTestReportController(IDrillTestReportService drillTestReportService, - IWellService wellService) + public string SignalRMethodGetDataName { get; protected set; } = "ReceiveDrilltestData"; + + public DrillTestController( + IDrillTestReportService drillTestReportService, + IDrillTestRepository drillTestRepository, + IWellService wellService, + ITelemetryService telemetryService, + IHubContext telemetryHubContext) { this.drillTestReportService = drillTestReportService; + this.drillTestRepository = drillTestRepository; this.wellService = wellService; + this.telemetryService = telemetryService; + this.telemetryHubContext = telemetryHubContext; + } + + /// + /// Метод получения данных drill_test и drill_test_params от панели оператора. + /// Сохраняет в БД. + /// + /// уникальный идентификатор записи drill_test + /// запись drill test + /// + /// + [AllowAnonymous] + [HttpPost("api/telemetry/{uid}/[controller]")] + public async Task PostDataAsync( + string uid, + [FromBody] DrillTestDto dto, + CancellationToken token) + { + var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid); + if (telemetry is null) + throw new Exception($"Telemetry with RemoteUid: {uid} does not exist."); + + await drillTestRepository.SaveDataAsync(telemetry.Id, dto, token); + var idWell = telemetryService.GetIdWellByTelemetryUid(uid); + if (idWell is not null) + _ = Task.Run(async () => + { + var clients = telemetryHubContext.Clients.Group($"well_{idWell}"); + await clients.SendAsync(SignalRMethodGetDataName, dto); + }, CancellationToken.None); + + return Ok(); } /// @@ -37,7 +84,7 @@ public class DrillTestReportController : ControllerBase /// Ключ entity test записи /// /// - [HttpGet] + [HttpGet("api/well/{idWell}/[controller]")] [Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)HttpStatusCode.OK, "application/octet-stream")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -60,9 +107,9 @@ public class DrillTestReportController : ControllerBase /// Параметры запроса /// /// - [HttpGet("all")] + [HttpGet("api/well/{idWell}/[controller]/all")] [Permission] - [ProducesResponseType(typeof(PaginationContainer), (int)HttpStatusCode.OK)] + [ProducesResponseType(typeof(PaginationContainer), (int)HttpStatusCode.OK)] public async Task GetListAsync([FromRoute][Required] int idWell, [FromQuery] FileReportRequest request, CancellationToken cancellationToken) diff --git a/AsbCloudWebApi/Controllers/SAUB/DrillTestController.cs b/AsbCloudWebApi/Controllers/SAUB/DrillTestController.cs deleted file mode 100644 index 45330d26..00000000 --- a/AsbCloudWebApi/Controllers/SAUB/DrillTestController.cs +++ /dev/null @@ -1,69 +0,0 @@ -using AsbCloudApp.Data.SAUB; -using AsbCloudApp.Repositories; -using AsbCloudApp.Services; -using AsbCloudWebApi.SignalR; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.SignalR; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace AsbCloudWebApi.Controllers.SAUB -{ - - [Route("api/telemetry")] - [ApiController] - public class DrillTestController : ControllerBase - - { - protected readonly IWellService wellService; - private readonly ITelemetryService telemetryService; - private readonly IDrillTestRepository drillTestRepository; - private readonly IHubContext telemetryHubContext; - - public string SignalRMethodGetDataName { get; protected set; } = "ReceiveDrilltestData"; - - public DrillTestController( - ITelemetryService telemetryService, - IDrillTestRepository drillTestRepository, - IWellService wellService, - IHubContext telemetryHubContext) - { - this.telemetryService = telemetryService; - this.drillTestRepository = drillTestRepository; - this.wellService = wellService; - this.telemetryHubContext = telemetryHubContext; - } - - /// - /// Метод получения данных drill_test и drill_test_params от панели оператора. - /// Сохраняет в БД. - /// - /// уникальный идентификатор записи drill_test - /// запись drill test - /// - /// - [HttpPost("{uid}/[controller]")] - public async Task PostDataAsync( - string uid, - [FromBody] DrillTestDto dto, - CancellationToken token) - { - var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid); - if (telemetry is null) - throw new Exception($"Telemetry with RemoteUid: {uid} does not exist."); - - await drillTestRepository.SaveDataAsync(telemetry.Id, dto, token); - var idWell = telemetryService.GetIdWellByTelemetryUid(uid); - if (idWell is not null) - _ = Task.Run(async () => - { - var clients = telemetryHubContext.Clients.Group($"well_{idWell}"); - await clients.SendAsync(SignalRMethodGetDataName, dto); - }, CancellationToken.None); - - return Ok(); - } - } - -} diff --git a/AsbCloudWebApi/Middlewares/SimplifyExceptionsMiddleware.cs b/AsbCloudWebApi/Middlewares/SimplifyExceptionsMiddleware.cs index 3180f41d..0bdf0683 100644 --- a/AsbCloudWebApi/Middlewares/SimplifyExceptionsMiddleware.cs +++ b/AsbCloudWebApi/Middlewares/SimplifyExceptionsMiddleware.cs @@ -56,8 +56,8 @@ namespace AsbCloudWebApi.Middlewares private static string MakeJsonBody(ArgumentInvalidException ex) { - var errors = new Dictionary { - { ex.ParamName, new[]{ ex.Message } } + var errors = new Dictionary() { + { string.Join(", ", ex.ParamsNames), new[]{ ex.Message } } }; var problem = new ValidationProblemDetails(errors); var buffer = System.Text.Json.JsonSerializer.Serialize(problem);